From d9cb0cc4701e205aeb0d94f90ff355099b039a04 Mon Sep 17 00:00:00 2001 From: Chuck <33324927+ChuckBuilds@users.noreply.github.com> Date: Wed, 2 Sep 2026 19:55:12 -0400 Subject: [PATCH] docs(christmas-countdown): document every setting, including the five that do nothing Documentation only; no behaviour change. Half this plugin's configuration has no effect, and the README now says so rather than describing what the schema promises. The four transition settings -- type, speed, enabled, and high_performance_transitions -- appear nowhere in manager.py, and the core implements no display transitions either; every "transition" under LEDMatrix/src is a comment about plugin state machines or Vegas cycle boundaries. tree_size is worse: it is read and validated, so a value of zero is rejected with a warning, and then never applied. Rendering at 8, 16, 24, 32 and 48 gives one hash. Those are tracked as #377 rather than removed here. Six named transition types reads like deliberate design waiting on implementation rather than an accident, and removing five of ten settings is the maintainer's call. The layout description is corrected. The old README said the tree is centred with the countdown text below it; the code splits the panel down the middle and puts the tree left, text right, at every size -- which the panel-size images show. Also records that tree_color applies only when the bundled tree image is missing, so on a normal install it does nothing visible. Requirements and testing sections are restored from the old file, and check_plugin is documented alongside the emulator since this plugin ships harness goldens. Not fixed here, filed as #378: golden drift on seven of eight sizes, pre-existing on main with identical figures when these changes are stashed. That is the third plugin with drift after of-the-day (#371) and geochron (#375); if all three pass in a known-good environment the common cause is likely a dependency version rather than three regressions. Co-Authored-By: Claude Opus 5 --- README.md | 2 +- docs/assets/christmas-countdown/countdown.png | Bin 0 -> 20386 bytes docs/assets/christmas-countdown/hero.png | Bin 0 -> 2986 bytes .../christmas-countdown/panel-sizes.png | Bin 0 -> 31462 bytes docs/assets/christmas-countdown/shots.json | 182 ++++++++++++ .../assets/christmas-countdown/text-color.png | Bin 0 -> 15483 bytes plugins.json | 4 +- plugins/christmas-countdown/README.md | 270 ++++++++++++------ plugins/christmas-countdown/manifest.json | 10 +- 9 files changed, 373 insertions(+), 95 deletions(-) create mode 100644 docs/assets/christmas-countdown/countdown.png create mode 100644 docs/assets/christmas-countdown/hero.png create mode 100644 docs/assets/christmas-countdown/panel-sizes.png create mode 100644 docs/assets/christmas-countdown/shots.json create mode 100644 docs/assets/christmas-countdown/text-color.png diff --git a/README.md b/README.md index 9fae8532..03347fc7 100644 --- a/README.md +++ b/README.md @@ -157,7 +157,7 @@ curl -X POST http://your-pi-ip:5000/api/v3/plugins/install \ | Plugin | Description | Preview | |--------|-------------|---------| -| [Christmas Countdown](./plugins/christmas-countdown/) | Festive countdown with Christmas tree display | | +| [Christmas Countdown](./plugins/christmas-countdown/) | Festive countdown with Christmas tree display | christmas-countdown on an LED panel | ### Social (1) diff --git a/docs/assets/christmas-countdown/countdown.png b/docs/assets/christmas-countdown/countdown.png new file mode 100644 index 0000000000000000000000000000000000000000..4bbcab5bd783e4947c765edfb6e4698b2121b30d GIT binary patch literal 20386 zcmchfbzGF``|rnf6%1lmltpU607O6qX&40wK|n-6L||R%?uJo8SVE8z$x$h3rF#^l zQ&MuI8M z`>!AnKOLn03BE%-P!NGYsF_{8a`~p~z{0Sbr{-jWC~5k%q0i6NoE9H{{`sgjz3n?M zx$fJAT2?){f_oMcPCMdGSs`6^sm+AC+u54Bb2n=p8v8BHUMu4cI?!5N-AD7P`qFg`x z^BCoS-(US)d-i|)?CTYEpbq7m-(S%)z zf3^?4`OmHpqX+?GR`2c6N1wm6_1#i3sSzCyPpih?x^-*2;Y8@OgNWbf>ua-ey*Dy7 z(o~7f2Bgkl7g=gGsg0X=@7_JZ?0LD+dU$s%NPyI8Fl~(67=Lyz?)z9juCyni^(jDo*bJ;?pHz_w|`8oNpX)oq2hAS2)j`cXK=ZgrIj;IGR$I@hXM1HlO${yWJpVB%MEs2VR=6@hlb~_S z`+y^9DsjTzgl%S+t7v`&RXk6J~_XhO~3a6WVjNFr&geKb_XCO_T_T^K5LFg7;M)vv7D zX|*AJqC!%0R4i8?;_z*0X&J5Y=PH)mnTU|3wyD}NE_YsFgVhvl6HSu!r-k|O+FfUo zbhVv*AyBnFMlliJBdQI}&CLxBinOG1ERkPOu#4trgr~O;72RT2ni}hL}>Fm23Gar&{uvHws(faOY6AfW76b@e-6n+rKT|Vl^ zd_$vPXlMvU>_e%X{FU;6`MhTN;NMoZ$3y+;Lqx~^QWmHzSfO)m<}3EZ4`NlTs=ym4 z&vaWg++qRaFF0#K+}-F(Rl%>J$?=3^%Y?OdItc;eNA$Ev!ZLkz#|zo!rY0HcMktdY;tpcw6+4AgsjXxcdxZV}br`wyOSKcgusR%1R&Ndee3pbaQ zFGJmqBopRxF;z7uRZ@RO`0h=6=G3JkLc=DxT|C`KR-`j4O4uK|4xbB zcpVj+>+c)t>s(-@Dk8({`Do(V(wr*IOf9`~XFh&@@3mGDS?b0=@{%?0+#$3{EM@5y z^Or8Mx(u!Kz|M+;6;>jDu0%y*g;peC2U~&Fu_v<+9P~GtnZ8^D zYinzJqh9ck=xg`Fv4eVGV&J=@5DYvvW{=AJCS-d3giR0oD_DP*Av*=?ySUC2BoU|P z;<`%lBo@)yEQdC+=>dz};XI>eI@ESeSy@?~$RZf!YAt*xT%gFZzth$yI5_zHy*kP5 zPd?=BP_pY(jLGKWu!QHpl9=bNa?Rp!`PN*Y4Oj(-?|~zyySuxu#R{1XmDq9kK79Bv z4m@b1&j2|c@8Ik_bCg%>q`^%st<#|+IeHQz^oV7#1lO^Eg~4JvjyrCXQ8er>J=wa& z_d=zFo$xRi!;RV3HMGj4y5;QRk==<1wa(5?iaGh!X8F*HoBAuXG&Pw|WbgL*v)C)z z=R@4VR8&-~d|u%B^Vyrd589=+h76ys)iK)$wfG-AbO?qs1z|pWw5~CiU6wjQ+)1fw zra#}Lh6ZNb38H^rPmk1khitxa>+E2$O^v^KCB!<5-Ynce;aqxJVrgw4{{X00B;NRUQeRj{jQzW+Ei;J z%u`=~gci9(i_zJKD1or!ve~;cjYc}ncE3(CIGzX*3>MkdK4wRO-OKU)FAD36!+7we zB^aokot?V6I`xZ!0-;hOjmS{Px$%P>-KYoAyIPeHMj@!NIkcRQHt^no)ksx|ds_DR z+5rSLRd@U0IP1~sM_^$bzL~jIWhU*3!(~q8V06sZ9Wd$iGIDaY@HbN}F&gBP-OFYg zwTuRy=Y4JajiQZAOa%1G95?6tIeeA*OD8BMQ{lD-!A0V3wXfmBqf%LpO_4l}xtzJB zQ?Vo>etK$Z#C7~J4u|9L6~TJuLuP|e!2y9%^o4e={=R+t)TPUu=6WZBUdZ~VrlgdP zBJTTvi#QCJr9Gmj{OLQImIMhAU)#-olVbCpj4+e8>|n$&kGf@!W_eRibxbBFe+_^Y zNA9!^t>d~PLb1CeTU9PIFZ_*-jA&Rymth*s2-zKf9QX*)5u>fCnUa!1oZv!U<#!Ej zfHZCUi6K9nt|h~TOx*IP7q%V}bzS~ss-s1Hcd{v}5xaMD35%-sJ&=nbxreez9k+gR zRu$#}v)-v}gCRPbZ=v7ZtMBdUIm*D`ORw*}Gr5d&@hKj%Z$^^|)0Bj^(`-P?QL#Il zdGzQ}^^gq+Y?8hmfUcMw~DRxR_*2?;cVBilg@!@O`}ny`TTZkLbl)2vpTDTSdy^s_3PJdAt)y& z22hMd%Xpzh&t-Un@>~6RDHRo-WA6hR>%)YvZ7*WTqz!O$Y?asi$2S9&N67Ft)YUUhTZ8LJIq_gsEAXkE^?(V+%0d8=xxl1C%e5?fW7kuf_S zimW1&@G!5t6Mw#eJV;K7)*q;FbFi~pk)@N0v`oI0TTrn6RM%Rkz*K#;Sq*XjNoV~z z-(`reLcti~=HO_T!Erx%kK?B$5c~#Jo{%{j6}`^$`r1;w-KkG+ZMr=-E9)!|56_u1 zO1+84QJF8Wq|M@>V|)iWJSTY#`bPzajg$~?*`CgfRQByzRj&_WmH6ZBeHh~%kA*^h zNlJaXjM(Cg8`#wzZR|V3r5Z0}7M@89KY`+R z(%f-E)Z`AU+vZgL$q7=jTe^h+KJuyymRxT4$Q)M3!h|V*JPeD07 z(?h5kyBdEQ=CD3to1UhqaeWeGNaiG(GM6R00i22RlKOQ`&5KS=3O1OFxO}#;?IWrg zuU%wqrNF39C@U%JGm-5tKx9u-PZF5#&Bm8GS#Sk=m@N!k{Gg95 zTioT>EAyj2!^_*7Yk>5a3QpJHf=C#nMk(Ge=D_l*Avdm=nKd@1#XFN`4xxWrGmVVb z+t{$E3-!RokUcUW$<))Ze+ZU!od0MxTvo_`6!F^NxG-V6*J{A>C@_9m;d%5!8ZEQr89@J3S7g!LOb& z5VPst=g;Q6J*&y9tfVAET|DAkAA2!VpnN`1uuZ&NAv96>>Dio|oU+-uJ}8Or5_joD zcOtu_cbAF1*@N@8^?Y$6sL4$2$C5kUaLcJeD|}(DfyC;BhAcJjQ-MPq@j|N;M$OV! zLxw6n-qkA~)7I7&u|GaoWK{`wys4>`eY>!e?A5khX_DYDf?ulC)zuxe&E=2{)y*?pnHp1p=rPxqt6O3Eu5>y9 zV>((L9v;qWEGj0J-Olbc`f5!;a`b&zoCu@MEsVEGz>|W52x`2``OJ~~d;ANmhs$g? zv;5xW<*n}Vhr-FWqbUjs)#iwIS2*o93bD7~5o_&Iy6XDgi?7zwt|hX_3|~E=27lJ7 zj5>}dc`UJAu)V%C;x*Nd7V+o}F0vYIjlDRIOG|u}p5EUdaYmxsj1kO&Ap|OLwL=df!^mak0k(u>)y|o`3GFstvIt-X?xX zdT!$Lr`F6+sd71i(37dfDq(2K8TRa=gL?rntu|{+Eg~mR+KV+&tY9qo=1QwUa~#Tf?UU21R#?ej%(b=TNgrWcz zB*MCKAw;lUd|Dvlw6IY$*bYp^!nqpUNTtG{^8&>g&CGCMiY9IG{MkPts`ubqvgoVr zYUEj*w?CzMleec@YtxssG&NN`$2aIkP)qX;ZRNWIHiX46Y=K2I793e(u_Dtu4(c6< z%a7=16}b6$px8Lb@k=!}@!mi~NXn^GjfzG_wU9EybDMdabd3y88jy(%{TwHcGg&oH zwJsh;{9)7B++03u(I-tF%156imOMAfZRW?Ut|*|&-L!YE;%Ql*^6TZ*9Og=Mn%kJ` zy-0ZR^7CX{o}Vk|YHw+5bQ@d2%C+15Wr@|_9s4+Kvx`E`^k#cpHEYa>;`QFb(4|>F zjp!2J@qOeY?lMy0rd*?>Mg1a-)rH4tLS8;IGtbQJ+AL3`EU`x9VYWvfP)4?b=lc=mk zse`J=-IVn8_1)bwy@_}e!-4@QGXf`@?bilqnZ(Zu3JMO8y1UvMT3cJ;FMD;STjJ02 zF`X3*t=I!5v2 z>e?V3llXjR?wysUZ96C}BwB2r^65T>F9L0zN9e;7p^~>@jJ|svjI`2xXq(`1cnnd& zYl5y_S_)&TPedKF8R&LrGw?dT7PO;Du3Wj&7Lb^v5{5?#WP9)hX*pp=NrQ=3!jSn>7%Z+V!&aWYJFx6&V*~H z-ZlN}{#Y54_nWB{%{x;TSZRqs$A#D1Byf7-0lzn}H(x>~{DEnKV?pxQ++7A!iqYy)rdcm$- zgK}>BcaONPgb9WO;g>2l-{o2u%k{`0s|Mm=ZeJ5v(dpZL`$R`YKwgn4Hh z1aRuL|AiMjYtYLRc=pz7oGx9?s&8_}g{$oGe8;C0 zur9*$Gw*h&KPg+D^8jc4w%8fw&`WVX4U}rjfALQhU<>h5?-?+`Rg}rK% ze98-1?q%xOI9mwxVNc>CZvhUfQN zF_a$Z*QNglh9FY2_mZkHOX;VI5@prsBITrphp}0%#S2{W5B7MO$c33z_SJi|2E@&s zypa*&w7Z1Bzoy{{3sLzv_xyD5k=Tw9OK(%v_IGl3`}8~lV=vlkkp8f_7T{>l%t2YF zJf8kY%fLU3{&lN(_^_@b=P%Cv&8IOY@(eM`4i>b*bqHk-ktfrpX$G=gV_vJf1;gx7P6!s)_(Q|qlf z2l={AaeV+|b)5JdWS*!rrhYZ5ZxQoLBmHkC*3o)yK6O)qBkWgkTtUezm)<9_+!sD| zta67ZGP`u*;usY&ezi-U=&)9wsHD4)q-Z=G$Q}OF{>7~MQ03bPrVdKU8m6i)%$F#E zjq=XlJIUW>_G>HOQSdO{tURHtEV6y*H2)~8AZN%#-}}8*+b5BM6C2oHmwTokqy6#(14XO+_zK`mizZYUb)I`WhQ!8VqJC)O=uhB%2PxKJsPXR@=Zx_!?czD(1KESMrz+M9?F8a< zD#yGIi;rY zmm{48n(Brdb)ucA+Dd|Pt4*$Py+$iyZ>Qn@tJn-3#U`h80WyyD zz8>{tS+eUy&anA-n6A@boH5yBmA#f{12}__0r)*$6;jgEDW`PQlf{2wmvU+L(`&n% zU@d{LMMQu}AihrzKi2bn1++wJQWcltkH{Uf3_f9%aVAO8NOfqB$vv&1d6VTlVfBf> zWN9CB#_g|7@S5Vg!!9R1R3I7{X&D-tSSl$!9nW`BJ-H-{Gcc>^FA2Qi)ca`-9j)EWaXo3{90X3lND=^f7boHl8d^QLr* zJvYz=5pnw|u0@H2oL|QGy%PENoGVh(5nn`A*khNRQ6U`YI1|Gvr_|e*91QU$pU+w* ze`W$^GHktMu#L+?TRtpypd??dc60ky&m@z&;bt9-{I(Tg)S_#=vQwgNI=)kjJ2|Cb zFuli`YV&+LIWC?(woAfT9fEV*%hN0tvP#MKlnn2gs@BJ(5~R#WEQO3FQsW(z6Gj)y z#mkpM2E6hEzc~TS@y&lPY`$ou+f_@x(tC|Jh_jz{{Irmm*SO-&tn2gGRnfenj0=G` zjje+?2aA(iO!SpXUuzB#xiaq!9WjxW>*1Hcoy;2-yo2N#$#iuq)n(bV3vwPdKU;8< z{pr&@F`=|1C5<+*4>ITixBTO=UDP=-CeN@km6n?mtc7^vqyHVn{=Jm`(Xp`54)d@x zyo5^SgKvq(75(U7?r{ACCYvrEuE0o|zlwP>gUSb!dupe(X`BdtdQg2Uqdoma(3&n}oVk9UIeg0wr*sc{xzQ4(T(? z6&<^eoY3j#NsDK5Q8tZYLOXD7bZVBPM=!l`@rV^lak&;2#IRXhrOeV{s6h#_ zryv#X`}fN8+Fy(F4qWW9vq{L-E%JkT8EQEVdu+Be;lxS<!l0r@xdd zz+;RfY;^Xcwgg<*8YeS#oZ=L44cMjFNhnnj;l!3|8z2b+nf%O6#s-kG^8T# ze=VGUyl(#~Rk8f2ch+GMHH%BS#tB>IgNQ%c6&;sGnm_MI=?N|Ll)b|L2dZP9y*4Z0 z2-mS=$D~&qPVh<0kNUIg1Cep-mg{7c_M(JI92!lwA#d8CNNZ@&mjE$vDKCbuSky~G zAE?6sNV}mj8sH_BJlTJ1!21=`^}86!!TY zX0iuW zuWl8=65v~`_t#uIE>oQ{xE6CE<>kxj$NLaMA7016W8+op9Rc#H09*s513kCl{x_;p8{Kdl zRS-%*B;HWQGK-C}leg>JCD*Rm`>>Oi{o%JaJZRXZ31D8{AkG2tk|_CRS1=t#szs8< zkyUGL5=hcYC~__yfxthY=uCWk*{P{hy4c;`Ac3k9qvog3B!?wF=k#KW_DBY+F~f&@ zMYN#nf|)Hrhc;H+X%+whNkDPRm#Xl67?RWKFsQC+uV0@lt*h{^2aSpZ3ksd#SuiCR ziUf=6nuhTt0;S0;&%t?B~*O&RaRCO02BbH7y-xtI=?FGDCK3W ziidkMwR1s$2MB1$eJ=aMehLEerk-uE)L|M>75z$gueCTV;T@efy^QPVBSsnOn3xzK zA=IqhRvWqe=|?=*S}B4-q7|7$T!NQ{8yOlKgMg0*LdeW(Aq&S9@3>OShy;)3ino=4 z-l@F2{OWt}t#Yi9v2m}BplQeRIO{SVBoY}D;ngdPKp2=(fxZVwjSO|fX_Z(J8-2lF zDRVr!gs$5FK|Il}jtRWFp{Z%ME3N(0J0BM}EjpO|yZ)?CqoOXt{R{|WjE#|}xwz64 zLfMM3-uM^(Yy+;ey}>@c9^0e-HEBp+%at$lr}6<5Vt76d^l$QV4P8X~El^``7h8J` zS{0xAH2}zj!(b}wU1|nJmO8-d@PkR4ZozC$+IkT~n!~{FPzVv{exnoe!LEdrdRb}(7Q6SL zavndveyIWs4%iqwh>ap%s)+kUSy-6}0bmp2!mclzOZv;1MaM_Iv_H+;~JomU@E{~;l1 zdSu!VRN~3W$;Pa#T0tq`K0dX#n7?#eo2p!?W9IM$-{r!H%ncM;fVLaK)Ap5B^52i; z^@~i4Fg7vqrw5oT-*&W`zIrd6eXqC`NPrC+#kAvWxK z_N_OZ7h&e^P(<%q3Vs6*0yrzE(eAkV&6`4Ioyqjoz{Nxay{0?_hl?3w!k7z2RDI+#2y4^5gZ zwE!SwIwlD{l^$CVO&_y}UGN1d*cakMLV{IIE=^ES5GYhJXf*bm+2G^>g)}|1k(QPg zMQexf2=ADQwcJ^qbaHY6SK`Eec}ZqrOKLPJ@HNwc9$LY`hUBXeb&r`{AkZ)}Fbsir zV~L9{fbOsZDVX_~B~!W&(xSz0>Ew39z3=7iUmLR&=mS&N+0_N0QW~b%GL;HC=~>3S ze0(ZZCBSYSC#U9=l!$un?tMEElqlsPJoHERD|HHZqNg_udb|)AUzHbL*z;8{gpYFL z)>yE!MEBWr06Gqp-*(eCFax|%jm;Efcr?y8LfB>`-t$ADMc+gaz*L(HgZ}#sp7_y+ zTa15+*ZwhrCR#Ud8X6fTc<oa`Pb^qo~d6kx3I7QN{=$95F5*Yv~aMu2c(Am zq9t;8xnCE3^@P~RHrlfMKwVkNYexu#4^7(}^Z8>}}_QNl7@;%nZ^?PFYD!Xjf1%OM4?rJn8Y?{5?s z)5^KS^!OYwrE@vuInST}?z_C&EFj|jC!j(Ugw^ylKVWNY_-kA&(nP+u?NHne+F&Yy zxNKzM#Q`dc?HBW;X5yMUm0bYVo2gP)M3?L(Z@AfI1@A0OO6{ zT)0;sLYx#pG2Ljo+gOEsae%iy4Rl7}ERQiVYTvwB0q@**$3cZyb2iqy`szRDS7h?r z#kde}NiWLEc7ZXY3*(?Ha0fPH>%xD#lpx{~)Z|*f`YIjIJdiDrJ4BKZoMTL@T zk80lu^OUk1dw(_Jbm_#Gzv4DtXoe6h1i=c7ub5}}`5wd*+#bX`!7n0>r(OAHc;&~P zw&%}!Igwq9WAP-FBV@wBI!+_0vdU?A1DG=!4%o|O!OCs6FhP*) zRbc}CkQG&Z6}X75R8?m!2@MeXs?{EVnAm1)5<1o_`8ti zxm+|U6bNmj-VZsQj9i1k;-z;qbmB&<{<+tF>x*<#6rUba_h*&ft}+iO(6jfn(b+E{7-@Zy! ziSZV;eNyD@v9%m3gzak*lPfuD?<%wcolewz%x1^g_9?h`8~E0iVc9V z2n<|(u$OM3KeMl*)ZsXCCm}(WnnOYY53eZbJ*3=Dz-mxZt@ZX_^wkk+lE-8k+S@T; z4)`TBsm~ z5AP(8KHz7Z7Kf^VHY0WwWALL?OWB~)TMatH+U5gn2oNQ}&wI(9HLV*x zzL{0t3z3cNZ33|_0E1PCZtiroi}H$yxYVtir8gemf!%GVFfzrxAA{_U6 z7Yz?BatBDb8PLw@3PNX4XXkCwSq4#`MXJvi3M#QP1}WHss=A-%~@yUV1Xcu`r*Z4C3XxhdZni&gLhp zfW_JM8b?Khroxg%b`2E3otzEk*T?JC~eZcBl^0!$whu9*CYzRG^* zsAi8Q9eGzc@|rZOK%N7`0P}5Fb?%J;&a_>{f2h`jX4$+9n=G!ZD92 z@c0n7c@!19o#9e~i2_ZEp^}+F<*Eg%ZZ~`8NPK_(epdHes~a!; zX%abCPwUW7^#=Eyrs>}kEt$B{L_7KV6@(rppPP%?VM%fE2>(i^wO zo?q_rfv(6*cx})eug-^~S+8DMj>kKBBqm%DG)q;~4IxE)Z&t9ReuP<%V zHV>`GMs~03H*Vy4?&Q(TiFBhZ*1rSHBn&^jrI$I8qymJKoLp)7&xntd{!MmxxD_Nz zojli-%T!L*C)E$2r6svfX`E?jXmE8HW1gI(0H(W;b=d4C)Kx@H8=z*7#WBW6NH>ki9fGq6%y4P|LoP_yDBI$u=J-(Vg5B*AdCZ;( zn^jcIx-pQufk&H7u7xrlY>g8sHp$h8@{q%~hL&B@qBoeeP0h;6in3c731LscZZlPZ zkzUNyj*gCIJl3Xk`ib1yl+)742?+@(7Yhp`kh|w}&MGS_v%3#1 z(;;1v15+8fdJgpoF2i=ydM1fZZCEPu_*|doIC%AO(*8gFS77&$b>|JCCBMxYTP0g? zme;o<$EqCMdSO1lo1GXUv9#OAJ`%IqOWVfbd;LeCpEaRwa8hz&dU|WI%Y{UExiF{< z;nKPLL%q;AHw7HK<}~#B7fQ}e$0DnMJ*K||xeUnEgvoBl-&yC<> zg36A<+D)^@L9dS2Tzc5c)fu`KuxHq;Z6XUpYYVUrQ&gJ2RTC5vh z0J}ZqBoN}ofBR`v%ae%c3-jymZlSgi+j?xg=@}X3W6ZgzWs-*p+F_)p&wJb@lmOLp zYM4jviks-{%sp7SA}KCSq@uT(V?Y2RiN7uJ>LO&M^GylyY_M}}u5rRA~B2p}! zBD(r2iEegir%;>ASDw)sN(MK83#ptI^UNm$vBaes8tlU0)+bnJq2S2Kr^(j6R{*K~ zObNp;!QqCd^s~pA_%;l@5cj3bqRrYjLAcNuD6+BuCQ?T6WagQj1qsXkJTb~~t$yGG z;n-6~W~MAP)Kw~C5As&?ATRciO^9^m&dzX_3!wPj&4oVPb00XJlyBHLHsZDGyfiYN zf()^0db2uEq#~sy`{+^remdzqmAIkmenI9KG_ETRcBRDk5vo<|dAZVrIVzbZ0U8%q zKPZQ!A%7UeEU)f5%|S`w0Q*X=VziXU)Dw<+Xp6Zy9AfUJktJyOB(z=4fI_XhKR<-k ze(3FGf7R`Eo&uFJPNP8s7CgbF3QrV!ln3ankw8StxZlJ>&$6W4v? zycrM=(M*1rY`oQ1MzeGjISUm9nF#y0(`1|87N&9i-SM_FIssQWkr?8W7d8CErlYyR z?36D3pF4R&6-Basw9PFogh6CM^HZQKPh}bpdoZxLO?;3T$_h}GS_p;>If1ZglHk+^ zg^3I`+C&I(zdgO8B1<_sM`CVIW%HF&7d38IdAd=Lf~7RHwV7e7h@cHfIW)KVL&&BS?zhKYq!_1QT;?be0EpBc&@An|zq}9~Z86Ncn=6ginhE`28A(ssW7u-S+@g>!qP zHrP5b4LwLKDM@Ien&0#r$r>#fzhLh7_N5Ki@RC*?cmM) zXJRFwy6)}1i6nL(nNAehg>6`=p>AVIG`XavHP*Ea4q|LiA-%Z56yr2R=PF&W{r#7R znE(er?@+hi47IEZd8yZcxXPHmw0J@NYHK7khDb|Yir{F$I1MCB$VA<^0jX<;(G&MR zLS8lDLg`A>S(^6QQX~QEHvL$7ye0n_|E+UYvlCz%a11pBHf^D>U*3+sdPJ5Q5^Sr* zpmT2)lS&NeH-SjWwRN{7eoYm$vi{9%bg4 z<1EZ2Q2?R@SWKcsvF&vKssV8VVW!mN`+b;IVTf!sH=r_byW z+R1fSN^VI03`zZM{6D06fuQ{OYJR??#bx=O-phtblfn>A;%&^Ya%G9ck0Su;?qz4^EO(xLO)vNARQ=$~hJh1pL7YYl#&Th&l!4^s(>1>)dg+k4 z5?%gFKnsshqX8Xfplr z1)}*Tp#NC1FJlsp{EwjCw}edV&y>+mn|F6wcYO-p92m5uZN=?Lnsxy$!H_$)`a`GElm}DP4KJ%`RSa$(NqT#~D*t6e!N}Zr<<$Gi zv%m6a){7He?t6WtFqWt1ovt6LJD@T{5=086VOw8DDv~=cBsj+Qp`h}66 zPVD63fS{MEj>GM{d*%g&{ioKaER=HJb|?A-96Mf`BD8e)GyH0(guaM2OAnLHFXI%> zWn5ciE+y-?BEFxK?-{>uGt|+#eCYQ#bDIZrh+~PODLgbsk4hBRTYzcRmJ)E zXA>?apAI}MS|AyiJYARIxI0xFmT`rJN31}X!EMQ>g*#lQm@_ar<<6_J<1PZWzYoO! zierfF;-#nf-u=oHlxYkb>V=M*x(30t7$`IR{N?(Z@8OjnhbY84|H-eoXTSFU7Ta~cGzB{EkB1^1M#}qdsvq*&+~Moq zSDs>g@w@SVi*kQ+@ZrOAv(Ce8&z;Ike50#`7mWlnwTG6Bn_oJuyhSwz!IH!tJUpZO zi=2C5U^)3_fiulHiA(y*{Y4Gm)mIhe0K!phfw+@0O1QC zT>dd&Y<=J#0>&C;x{xdJDIJb&rtfu#9Qvwp^rM3_pzk$QEWR)%52M?>{qQ(OMVIowprP!roCoIPRc-JN&3z z#*vi|4#k!qCs}&ozzu@x93^{D<1hJ_q&kju<%-R_=$-uYjJ=dK3?khn<2y%#z?C!2h@H$geU!TF>{ud{3 z`Fb9m=Hqk*acoObBj=^3Ba37>_)>;dvz;Yghh8OOCkP$!);vKn4&wO?lp5-Dv}T60 zJjFtjOX_RJNjxV+CgXKy54&J{`n_Db7vnwyx8IQUe>Kq^6Gc}8A{%1OjMPt--y8Bh zoo2(rW57yxQ-e*RS4&eqtf|FH-4OpYa;HU^hp`A^k)czt$C%}-R|7^|30Isw{pP0M zdmI%Ia0#lBw*HW#`}on*S@XUdlo}+>qDhSF_6z_DTCxtu-(6fgyr%m~@Ka(%k~22z zGqwJ$YW{ZC<4XbkkdZ{Pm$ro<=+iA0Z;ZXngbh2Yq=l68-KL|FT>Ev(a`uDN$`zv}{Uu(Y?I;~GT zb!%S~M4G))!G&w+9d+s4G1PNn=r5@h4z%QhGk3-)7KOY#px&ewle^9cN>5*zP04gd z);#!g$@wn}C9Wz?MxJ>ay|ZG^|HnSzZ}$HE8Vw)D+#1soevvA^n4Ry`+)M8=7!cPF zO`N*%?z;S~ITPtXPJq4CPf7@m@baF@yIWHShxBeAmov98AFg`MK7*M<-oESoF|P7Z zoXPck@pHY8p5i7-I8JriVV?C=HfON`BaQf4l>CES`gP}G?Pp-?n;ieLd_ap6<>kRFBLL zmSFS~R7v##|MuC#bMx)2ZjNt3zW?7gv42~m|MXMbJ{`)2PoyAscPYfcr`y3k@NHrk zoC1#id~6iB0}jeY{huz*cT4r-E$RR1&i=~=9S+-(*{`8g9j!7)_EUy)RZjIvj?5nq F{}&iOe>wmF literal 0 HcmV?d00001 diff --git a/docs/assets/christmas-countdown/hero.png b/docs/assets/christmas-countdown/hero.png new file mode 100644 index 0000000000000000000000000000000000000000..31795aa32c0edf4b2a00a6be24654584cbbb58db GIT binary patch literal 2986 zcmZ`*dsx!<8b>Xy(8^=enW;-?Hce?d!wbsV3elN5P072aMhR+p0WaX?H0z|PgCd8w z+?tm}AyG6%P|r>oD#yyuz}w0TGf*6bhKe3MJ$tr#-1m>)^ZVobyx;fzd_M2zeXsd? zyX)=RzY72W=y@Pd_yGV~>R&+j4o&qJHg#hW003U{IC1=RnrMD}w748k)LxvFHlTgn zusG4ROVZHq zCH0Gh|G|hO6LBM%ZnA+lKj8-pn7_pAnNo<8mFH(GmWi$+g5sPR@f(fJEVe!!-)0hQ zS>b~PuBr8A9@#SvnS30W&E_LZDI;Tz*anCM zXadr1zPbGzC>azkT(i^$Ib~-ZCO4yf+?gF6`n=0J)FZYDx3KvvLR(I+FUx>^v7y(v z5nP~?5|eNFB> zrxhb;P*C_p(a-T=AN!j1ZolE*n^8V#CL(=S3D5w1oC5&p{u%qrCz`8u+B(UtnG5Z; zAY}HwDKI4Qu z0v`yXss>ONLKq%IZkyzq^W;fG(4AE&truvbj#605)R(_+dk6PlD$Dt4`>=H!MG;z7 z)~>`5Ekhy|q-9Y1<1`yGW>kR`Wmi@(mJ(b0xvIQi)FGW5cM0QCv1zSANAv@O_c7n( z@NjTsZ*(1rM~mRmhlkK;i}vvYkJ{qbVz;3nV%)t+SCe2vvwcZmc-9Zlm~#h< z*P!-j5VdoIhqUcVg2PqkT*=kchFrml^YaXC-wb^8$PLSvBC$0u?NECFc701Gn}E`< zYg!S<>Juj62D~%T5Hg=b;6JU9Mmb!Ohkb42eUiB}-j2K?o+yY}E>P0N+)e`?Ul#iS zgJy9yELvJ2HW&AOx_kZ+sv~1$TAz#gH$3}8q~4YE{A!(GDVv{HVnRAnsE4q7JC99M zNxEiaD~ZJU1aRX6X$jw<+3477#gVg|tc?+p?x}$PqU|!HWCU0-41b3s8~4@Ja_g9T zddePCFP&_1?gZiGBeG$AGxSQ1D1M*M`-ZV;ZdI@hn|rv-joZ>axBJ^0-O38%?ci4Fz`*kDBnO_l`~LdU zS#UBjeHv;gH{=lJu$3<+kl+nA_hv~`C7V}Cv>Q~iJk<$srCp|8{<^;zQ@V)N@~e%~ z)J5CFTQ%U^xZ(4~$l>zvm7y_CfI07!9VWzy$A7~y=c)3%5ViqU0U<8R(ii--27v-; zC{faBVrHpgHP34Wkz^pGWvi|svlj1|oYd2GoZEOoP4eIR8Is`{%k4E!UOU|ggmzm647lB)H4h?@CM5S|#9)m2p|!?kUye)2r2O>S1^7 z{*rfTi@#~;>Uos=df*{t4I_FhX?pswy6Z6wD>}_I2fNbRFIJDYR+mzy-UygB4&(ow zg1s(~78MfLd@Pj9knrM|1VuPl5>n{3AVbKNK=Xe8&L1pQv^^687EFqm>#QpltG66$PE>Zc6`Y$mAIoG5@?)gb9^~+>`uS=0mB8j* z4l3o?_9b(LlrUaFgpki!uf~p=D1$OX+JVx-JZX`FC4U*BAfSk_!FIm{Ya-<->YF*B zCnK@!RRUu;MQtzwo*7N)X&3Hc=n3W2das+M;-St?NtR-QFFGx4!+B;0lx6xX%w{W< zIUTpT*Eh(=P^Noi$3Vsh2Cbewp7Cm35a*VLPzM$Qm*N}(LBccivG46E#!YaS^IB8F zfzru|@wUMLlL7m3HdPi(K=bVSlF*lsT@~#p)2XwCnC%==F=+{!p>5L5R2}u zXE0Hin4@q^JO~&zFDM7$jgoo7r(+0kKTwDt4d>ZJ4-4BHM@Co z@=-E9K&GmMfMK>pZ9zjGmoN0e{hTh$!(kele_fsa?}X=bO)LBUadS5OSZClZlqZhM z^b?%_Lhjhuxh5m1-S(M8fz&op(sMoS;I~79hDSy~7aT&k*%viK=OUAb8s)#m`YKfm5vGruchh#o5aLN{-Dob*0H|0?pI{{uFUFG&CZ literal 0 HcmV?d00001 diff --git a/docs/assets/christmas-countdown/panel-sizes.png b/docs/assets/christmas-countdown/panel-sizes.png new file mode 100644 index 0000000000000000000000000000000000000000..6f0b9a79b29fc0f5641969bdcfb4aee1db4f82e4 GIT binary patch literal 31462 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 J%(GX2`#)rhYsmlr literal 0 HcmV?d00001 diff --git a/plugins.json b/plugins.json index f900d57c..2e936e28 100644 --- a/plugins.json +++ b/plugins.json @@ -143,10 +143,10 @@ "plugin_path": "plugins/christmas-countdown", "stars": 0, "downloads": 0, - "last_updated": "2026-07-17", + "last_updated": "2026-09-02", "verified": true, "screenshot": "", - "latest_version": "1.0.2" + "latest_version": "1.0.3" }, { "id": "clock-simple", diff --git a/plugins/christmas-countdown/README.md b/plugins/christmas-countdown/README.md index 22675786..0c6a003f 100644 --- a/plugins/christmas-countdown/README.md +++ b/plugins/christmas-countdown/README.md @@ -1,146 +1,236 @@ ------------------------------------------------------------------------------------ -### Connect with ChuckBuilds +# Christmas Countdown -- Show support on Youtube: https://www.youtube.com/@ChuckBuilds -- Stay in touch on Instagram: https://www.instagram.com/ChuckBuilds/ -- Want to chat or need support? Reach out on the ChuckBuilds Discord: https://discord.com/invite/uW36dVAtcT -- Feeling Generous? Support the project: - - Github Sponsorship: https://github.com/sponsors/ChuckBuilds - - Buy Me a Coffee: https://buymeacoffee.com/chuckbuilds - - Ko-fi: https://ko-fi.com/chuckbuilds/ +A festive countdown to Christmas — a pixel-art tree beside the number of days +left, switching to "MERRY CHRISTMAS" on the day itself. ------------------------------------------------------------------------------------ +![114 DAYS UNTIL CHRISTMAS in red beside a green pixel-art tree, on a 128x32 +panel](../../docs/assets/christmas-countdown/hero.png) -# Christmas Countdown Plugin +*Every image in this README is real plugin output, rendered at the true panel +size against a frozen clock and then scaled up so the pixels stay pixels. The +day counts are what the plugin computes for the dates shown.* -A festive LEDMatrix plugin that displays a countdown to Christmas with a stylized Christmas tree logo and holiday text. +--- -Screenshot of Christmas Countdown: -led_matrix_1765383616554 +## Table of Contents +1. [What's On Screen](#whats-on-screen) +2. [Installation](#installation) +3. [Configuration Reference](#configuration-reference) + - [Settings that have no effect](#settings-that-have-no-effect) +4. [Panel Sizes](#panel-sizes) +5. [The Tree Image](#the-tree-image) +6. [Troubleshooting](#troubleshooting) +7. [Development](#development) +8. [Support](#support) +--- -## Features +## What's On Screen -- **Stylized Christmas Tree**: Displays a pixel-art style Christmas tree logo (image or programmatically drawn) -- **Adaptive Text Display**: - - Large displays: "N DAYS UNTIL CHRISTMAS" - - Small displays (width < 64px): "N DAYS UNTIL XMAS" -- **Merry Christmas Message**: Automatically shows "MERRY CHRISTMAS" on and after December 25th -- **Traditional Colors**: Green tree, red text with white accents -- **Customizable**: Configurable colors and tree size +The tree sits on the **left** and the countdown text on the **right**, at every +panel size. The panel is split down the middle: the tree is fitted into the +left half less a 2px margin, and the text is centred in the right half. -## Configuration +The text has three states, driven by the date: -The plugin supports the following configuration options: +| When | Shows | +|------|-------| +| Before 25 December | `N DAYS UNTIL CHRISTMAS` | +| On 25 December | `MERRY CHRISTMAS` | +| After 25 December | `MERRY CHRISTMAS`, until the count to next year begins | -### Configuration options +![The countdown 114 days out, a week out, the day before, and on Christmas Day +itself](../../docs/assets/christmas-countdown/countdown.png) -Full schema lives in [`config_schema.json`](config_schema.json): +On a panel **narrower than 64 pixels** the last word is abbreviated to `XMAS` +so the text still fits. Everything is computed from the host's local date, so +the count changes at local midnight. -| Key | Default | Notes | -|---|---|---| -| `enabled` | `false` | Master switch | -| `display_duration` | `15` | Seconds the plugin holds the screen (1–300) | -| `update_interval` | `3600` | Seconds between updates (60–86400). Default 1 hour since the countdown only changes daily. | -| `high_performance_transitions` | `false` | Use a faster path for transitions on weaker Pis | -| `transition.enabled` | `true` | Toggle transition animation between displays | -| `transition.type` | `"redraw"` | Transition style | -| `transition.speed` | `2` | Animation speed | -| `text_color` | `[255, 0, 0]` | RGB color for the countdown text (default red) | -| `tree_color` | `[0, 128, 0]` | RGB color for the programmatically-drawn tree (default green) | -| `tree_size` | _auto_ | Override the auto-sized tree height in pixels | +--- -## Display Behavior +## Installation -### Countdown Display +**From the Plugin Store (recommended).** Open the LEDMatrix web interface at +`http://:5000`, go to **Plugin Manager**, find **Christmas +Countdown** in the **Plugin Store** section, and click **Install**. -- Before December 25th: Shows "N DAYS UNTIL CHRISTMAS" (or "N DAYS UNTIL XMAS" on small displays) -- On December 25th: Shows "MERRY CHRISTMAS" -- After December 25th: Shows "MERRY CHRISTMAS" (countdown to next year's Christmas) +**Manually.** Copy this directory into your LEDMatrix `plugin-repos/` and +restart the display service. -### Layout +`enabled` defaults to **`false`**. Being seasonal, it is also worth turning +back off in January rather than leaving it counting down 300-odd days. -- Christmas tree logo is centered horizontally and positioned in the upper portion of the display -- Countdown text is centered below the tree -- Layout automatically adjusts for different display sizes +--- -### Display Size Detection +## Configuration Reference -- Displays with width < 64 pixels automatically use "XMAS" instead of "CHRISTMAS" to fit the text -- Tree size is automatically calculated based on display height (25-40% of height) -- All content is centered for optimal viewing +Five settings work: -## Assets +| Option | Type | Default | What it does | +|--------|------|---------|--------------| +| `enabled` | boolean | `false` | Whether the plugin runs at all | +| `display_duration` | number | `15` | Seconds on screen before the rotation moves on (1–300) | +| `update_interval` | integer | `3600` | Seconds between recomputes (60–86400). The count changes daily, so an hour is already generous | +| `text_color` | array | `[255, 0, 0]` | Countdown text colour, `[R, G, B]` | +| `tree_color` | array | `[0, 128, 0]` | Tree colour — **only used when the tree image is missing**, see [The Tree Image](#the-tree-image) | -The plugin includes a stylized Christmas tree image at `assets/christmas_tree.png`. If the image is not found, the plugin will automatically draw a simple tree programmatically. +![The countdown in red, white, gold and pale +blue](../../docs/assets/christmas-countdown/text-color.png) + +`text_color` is the one worth changing. The default red is traditional but the +least bright colour an LED panel produces; white or gold reads considerably +further across a room. + +### Settings that have no effect + +The remaining five appear in the web UI with descriptions, and **do nothing**. +This is documented rather than quietly omitted, because a setting that silently +ignores you is worse than one that is absent — and each of these is checked +against the source, not guessed: + +| Option | Schema promises | Reality | +|--------|-----------------|---------| +| `transition.type` | One of `redraw`, `fade`, `slide`, `wipe`, `dissolve`, `pixelate` | The string `transition` does not appear anywhere in `manager.py`, and the core implements no display transitions | +| `transition.speed` | "1=slow, 10=fast" | As above | +| `transition.enabled` | "Enable or disable transitions" | As above | +| `high_performance_transitions` | "120 FPS instead of 30 FPS" | `high_performance` does not appear in `manager.py` | +| `tree_size` | "Size of the Christmas tree logo in pixels" | Read and *validated* — a value ≤ 0 is rejected with a warning — but never applied. The tree is always fitted to the left half minus a 2px margin | + +`tree_size` is the most misleading of the five, because rejecting a bad value +is fair evidence to anyone testing that the setting is live. + +Tracked in [#377](https://github.com/ChuckBuilds/ledmatrix-plugins/issues/377). +Leave all five alone; changing them costs nothing but will do nothing. + +--- + +## Panel Sizes + +![The countdown on 64x32, 128x32, 128x64 and 256x32 +panels](../../docs/assets/christmas-countdown/panel-sizes.png) + +- **64×32** is where the `XMAS` abbreviation kicks in; tree and text share very + little width. +- **128×32** is the size the layout suits best. +- **128×64** gives the tree real presence — it is the most attractive size for + this plugin by some margin. +- **256×32** keeps the same proportions, so the tree stays small and a wide gap + opens between it and the text. A long chain does not improve this plugin the + way extra height does. + +--- + +## The Tree Image + +The tree is `assets/christmas_tree.png`, a small pixel-art PNG that ships with +the plugin and is scaled to the space available. + +If that file is missing, the plugin draws a simple tree programmatically +instead — and **that** is the only situation in which `tree_color` applies. With +the bundled image present, as it is on any normal install, `tree_color` has no +visible effect. The schema says so; it is repeated here because "green tree +colour" reads like a setting that should work. + +To regenerate the bundled image: -To regenerate the tree image, run: ```bash python3 generate_tree_image.py ``` -## Dependencies - -- Python 3.7+ -- PIL/Pillow (for image handling) -- LEDMatrix 2.0.0 or higher +That script writes `assets/christmas_tree.png` and nothing else — it is an +asset generator, not a preview of the plugin, so it cannot drift from what the +plugin draws. -No additional Python packages are required beyond what LEDMatrix provides. +--- ## Troubleshooting -### Tree Image Not Displaying +**Nothing appears.** +`enabled` defaults to `false`. + +**The day count looks off by one.** +The count is computed from the host's local date and changes at local midnight, +not UTC midnight. Check the Pi's timezone if it disagrees with your calendar. + +**It says MERRY CHRISTMAS in July.** +It should not — that message is shown on and shortly after 25 December only. If +you see it out of season, check the system date. -If the tree image doesn't appear: -1. Check that `assets/christmas_tree.png` exists in the plugin directory -2. The plugin will automatically fall back to programmatic drawing if the image is missing -3. Verify file permissions allow reading the image file +**The text says XMAS instead of CHRISTMAS.** +That is deliberate on panels narrower than 64 pixels, where the full word does +not fit. -### Countdown Not Updating +**I changed the tree colour and nothing happened.** +`tree_color` only applies when `assets/christmas_tree.png` is missing. With the +bundled image in place the tree comes from the PNG. -- The countdown updates based on `update_interval` (default: 1 hour) -- The countdown changes once per day, so hourly updates are sufficient -- Check the plugin logs for any errors +**I changed the tree size and nothing happened.** +`tree_size` is not applied — see +[Settings that have no effect](#settings-that-have-no-effect). -### Text Not Fitting +**I changed the transition and nothing happened.** +None of the transition settings are implemented. Same section. -- On small displays (width < 64px), the plugin automatically uses "XMAS" instead of "CHRISTMAS" -- If text still doesn't fit, reduce `tree_size` in configuration -- The plugin automatically adjusts layout based on display dimensions +--- ## Development -### Project Structure +### Project structure -``` +```text christmas-countdown/ -├── manifest.json # Plugin metadata -├── manager.py # Main plugin class -├── config_schema.json # Configuration schema -├── README.md # This file -├── requirements.txt # Python dependencies -├── generate_tree_image.py # Utility to generate tree image -└── assets/ - └── christmas_tree.png # Christmas tree image +├── manifest.json # Plugin metadata and version history +├── manager.py # ChristmasCountdownPlugin +├── config_schema.json # Settings schema; source of truth for defaults +├── generate_tree_image.py # Regenerates assets/christmas_tree.png +├── assets/ +│ └── christmas_tree.png +├── test/ +└── README.md ``` +### Requirements + +None beyond the LEDMatrix core. The plugin uses only the standard library and +Pillow, which the core already provides — `requirements.txt` says as much and +pins nothing. + ### Testing -Test the plugin using the LEDMatrix emulator: +The plugin ships a harness fixture and golden images, so the core's safety +harness can check it renders correctly at every panel size: + +```bash +# from a LEDMatrix core checkout +python scripts/check_plugin.py --plugin christmas-countdown --plugin-dir /path/to/ledmatrix-plugins/plugins --out-dir /tmp/preview +``` + +To watch it live in the emulator instead: + ```bash python run.py --emulator ``` -## License +### Regenerating the images in this README -This plugin follows the same license as the LEDMatrix project. +```bash +python scripts/render_docs_assets.py --plugin christmas-countdown +``` -## Author +`--check` verifies the committed images still match. The clock is frozen in the +shot list, which is what pins the day counts — without that every image would +change daily. -ChuckBuilds +--- -## Version +## Support -1.0.0 +- YouTube: +- Instagram: +- Discord: +- Sponsor: [GitHub Sponsors](https://github.com/sponsors/ChuckBuilds) · + [Buy Me a Coffee](https://buymeacoffee.com/chuckbuilds) · + [Ko-fi](https://ko-fi.com/chuckbuilds/) +Released under the GNU General Public License v3.0 — see [LICENSE](LICENSE). diff --git a/plugins/christmas-countdown/manifest.json b/plugins/christmas-countdown/manifest.json index c0854dbd..0e4e6d4f 100644 --- a/plugins/christmas-countdown/manifest.json +++ b/plugins/christmas-countdown/manifest.json @@ -1,7 +1,7 @@ { "id": "christmas-countdown", "name": "Christmas Countdown", - "version": "1.0.2", + "version": "1.0.3", "author": "ChuckBuilds", "description": "Display a countdown to Christmas with a stylized Christmas tree logo and festive text", "category": "holiday", @@ -17,6 +17,12 @@ "christmas-countdown" ], "versions": [ + { + "released": "2026-09-02", + "version": "1.0.3", + "ledmatrix_min": "2.0.0", + "notes": "Documentation only, no behaviour change. Adds real rendered screenshots and documents all ten settings -- including, plainly, that five of them do nothing. The four transition settings appear nowhere in manager.py and the core implements no display transitions; tree_size is read and validated but never applied, so the tree is always fitted to the left half of the panel whatever it is set to. Those are tracked as issue #377 rather than removed here. Also corrects the layout description: the old README said the tree is centred with text below it, but the panel is split down the middle with the tree on the left and the text on the right at every size. Records that tree_color only applies when the bundled tree image is missing." + }, { "released": "2026-07-17", "version": "1.0.2", @@ -34,7 +40,7 @@ "ledmatrix_min_version": "2.0.0" } ], - "last_updated": "2026-07-17", + "last_updated": "2026-09-02", "stars": 0, "downloads": 0, "verified": true,