From 297c0c20f5f4e2971eebc77619295e2c349b3370 Mon Sep 17 00:00:00 2001 From: e2002 Date: Fri, 11 Jul 2025 12:26:04 +0300 Subject: [PATCH] v0.9.511 --- README.md | 14 ++ yoRadio/data/www/dragpl.js.gz | Bin 440 -> 440 bytes yoRadio/data/www/elogo.png | Bin 761 -> 0 bytes yoRadio/data/www/elogo84.png | Bin 3794 -> 0 bytes yoRadio/data/www/index.html | 107 ------------ yoRadio/data/www/ir.css.gz | Bin 1235 -> 1326 bytes yoRadio/data/www/ir.html | 49 ------ yoRadio/data/www/ir.js.gz | Bin 988 -> 1026 bytes yoRadio/data/www/irrecord.html.gz | Bin 0 -> 984 bytes yoRadio/data/www/logo.svg.gz | Bin 0 -> 7039 bytes yoRadio/data/www/options.html.gz | Bin 0 -> 2251 bytes yoRadio/data/www/player.html.gz | Bin 0 -> 2966 bytes yoRadio/data/www/script.js.gz | Bin 5965 -> 7106 bytes yoRadio/data/www/settings.css.gz | Bin 2454 -> 0 bytes yoRadio/data/www/settings.html | 261 ------------------------------ yoRadio/data/www/style.css.gz | Bin 7442 -> 4382 bytes yoRadio/data/www/theme.css | 16 ++ yoRadio/data/www/update.html | 38 ----- yoRadio/data/www/updform.html.gz | Bin 0 -> 572 bytes yoRadio/src/audioI2S/Audio.cpp | 20 ++- yoRadio/src/audioI2S/AudioEx.h | 4 + yoRadio/src/core/config.cpp | 77 ++++++--- yoRadio/src/core/config.h | 4 +- yoRadio/src/core/controls.cpp | 7 +- yoRadio/src/core/mqtt.cpp | 9 +- yoRadio/src/core/netserver.cpp | 86 +++++++--- yoRadio/src/core/netserver.h | 53 ++++-- yoRadio/src/core/options.h | 2 +- yoRadio/src/core/player.cpp | 18 ++- yoRadio/src/core/telnet.cpp | 3 +- yoRadio/src/displays/nextion.cpp | 4 +- 31 files changed, 240 insertions(+), 532 deletions(-) delete mode 100644 yoRadio/data/www/elogo.png delete mode 100644 yoRadio/data/www/elogo84.png delete mode 100644 yoRadio/data/www/index.html delete mode 100644 yoRadio/data/www/ir.html create mode 100644 yoRadio/data/www/irrecord.html.gz create mode 100644 yoRadio/data/www/logo.svg.gz create mode 100644 yoRadio/data/www/options.html.gz create mode 100644 yoRadio/data/www/player.html.gz delete mode 100644 yoRadio/data/www/settings.css.gz delete mode 100644 yoRadio/data/www/settings.html create mode 100644 yoRadio/data/www/theme.css delete mode 100644 yoRadio/data/www/update.html create mode 100644 yoRadio/data/www/updform.html.gz diff --git a/README.md b/README.md index 7b67165..774e3d2 100644 --- a/README.md +++ b/README.md @@ -234,6 +234,20 @@ Work is in progress... --- ## Version history +### 0.9.511 +**!!! a [full update](#update-over-web-interface) with Sketch data upload is required. After updating please press CTRL+F5 in browser !!!** +In this version, the contents of the data/www directory have changed, so that the first time you flash it, you will be greeted by WEB Board Uploader. Just upload all the files from data/www (11 pcs) to it +- fixed a bug with saving smartstart mode +- fixed a bug with no restart when initially uploading files to spiffs +- fixed a bug with hanging on unavailable hosts +- fixed a bug with attempting to connect with an empty playlist +- fixed a bug with passing strings with quotes in mqtt +- fixing some other bugs +- rewritten the web interface (almost), added bugs 👍 +- added listening to links in the browser in playlistEditor-e +- added reboot format and reset buttons to the settings +- the beginnings of theming (theme.css) + ### 0.9.434 - fixed the issue with exiting Screensaver Blank Screen mode via button presses and IR commands. - reduced the minimum frequency for tone control on I2S modules to 80Hz. diff --git a/yoRadio/data/www/dragpl.js.gz b/yoRadio/data/www/dragpl.js.gz index 55df2e049ec648eadf54e266294c8d27bd29f811..57bd7a87d8c3ae38331e35c8b632967ed37672ef 100644 GIT binary patch delta 17 YcmdnNyn~rTzMF$X%R4P&BgY0t04v@E<^TWy delta 17 YcmdnNyn~rTzMF$1LFZf2Mve`P05A6ihX4Qo diff --git a/yoRadio/data/www/elogo.png b/yoRadio/data/www/elogo.png deleted file mode 100644 index 9d9d42ce3740ae33e11367c44142fde489b207cf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 761 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I3?%1nZ+ru!8UuVnT!HlUL&0}WM%*|YeB($6 zh;bz3_KEPD$3kx%4+C<6B#?XSSQrq2#E*so(e2~mK=z#z5kLk+3tapTSTRrvC=SsM zWxz}TX@nVj?O>3Dq26SmBeY6_{DK*NbN~3l`X=lAVzK#6r}qXwzSr+#-(mdW`OR7G z$1T-mH|p{o+F2T-ye3{L`AG-^1LI#$7srr@!*8eEoHpA)z~w53$`L-co{#T78om7g z|A3E7j^+`MvriN))r;?YEqm3Gx6<&pd#BLSN7|R4>{x!u?zU#`efx_S=9$k{uLhEdUHKc8LTdNxC*n(;vRCFzm^Udx66 z-Nlc#zCL=(#$-GHUfYfTC(Q1d8dSLT-;~{U`ivj=94=NHzpZ5a!9C$@mj`2gvwF(! zvd;AlJum(rD{PwZB)(wI69>tcc7Dv0ie~0=EVpkAeCrcd&)*Es+;B>^ zIrBPk!5ix;QL8Ikc5U!Z4u2wctg&#@%J(1oW_jq(j(*@C?XdFiQp0m9Id6_%@Xg{}@vq8(xjv$qTUB9mZ_#3IgU0zc?B3k@ z8Q)~b>-FB4Q86p4>)^HHNyncRKS?{hJ?Bi_J)d_e(h|lC&#vBV?7%cjWbYaA(!D2& zZ>Gp9xSVSda%T`f#4d5<>fhMs8H>~XraYF}eRDzUBmsdX7QN>+WR|@?@O?>(ccZYw zIS-dY#`SNMZW}2DPA=Q`^6OEp>|2%M&d1tK{y5G$IyL8}`1+rGrhoQc?tf+24@^D` Mp00i_>zopr0D-1@wEzGB diff --git a/yoRadio/data/www/elogo84.png b/yoRadio/data/www/elogo84.png deleted file mode 100644 index ee369bfccd398a34df8c84f904f7b082eed28eb0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3794 zcmXw5cQ~8v7k;eTqoG2yw)%W_jSy;&7`1EFXi=-E)-I(+ONxqFHG-mp)-F1zy(>|% zg$}bds`ev3pwg-SO0O|m2Q2v+yFWF`R^+Lg4Kl;&}*lGdsNB^z1TC7r2K-CSh!~&Fr*Z|o7 ze@hdj0susN2xnLV022NBx3SG)8vuw0l7>8Fetw>e z^M3=NmwfyPKobB^3$fh-0zkGx36{w`P~!vuBy!vg05s|o0CLI4Rsfy@KnnoG0|EYG zAV3G%phe~Y*a9FB0BFJ#092tdY(+?l@DUr~P5>GJCs2n|%piH_gL-drG7G~XHrs=CNAQbE3^RyO% zWEZ?8f4KcSY$q~pA^2JM+=wFllQhScDBBNSreVAdw8-~3rOr4d!d->A2>Hnf`Tii; zL0_pahJ4=@I0xQbYD-b=Hsbps#l9eRdJRrbOjql=CN_8F{FDX{Ns4{mkZ(+qU2&ur zS|3ydT9{Y@D=OOFc1G%>%u8!*R8z0wBLc7TFx8%AW1>6W+gbWXeDCh8r+tS0)Y1OZ zWNU6(oUglsj1cE!UCG@LA4?PTMM+6fL4IBY>(`;T&vCfaQCp5~^KLR@~N)y4eCNa)wgFkzshY2`Vyn&aWXq0iOjyv|aB zq_LtyQ>XIN#d%X}#?W(WB|U5sMqF9x8h629Fw0H5P9F8s0%!U8|4p#1(kZUa?GV-* z4v+jeFfe%QeaJr|uL^#j0Gq~qkJ+%9ng)$2IvnBw+dJE`~-8C&@lq7=G{OB@l0zsq=bVXTgvd9zZ~3iV_2i^>8d zEtC}`7z0I~i^-08Jw3NNRwBW*V-pwCDnQPzXU@x#Ip? z$hwCfoFyTv8(At!8wOgM8d7YiN_^;+yP0g5AM)Pu3pd(|*%+yQEoskG9tQUifsbk| z>kEzB<^`q{30?7O%^hcP8Vl56v1m}k5 z^o3uVH3HN0xaRhNXt@~C**Tv}oXPZysfjT z0quxc6X5b_AE-{)c_L%Zmv*T7AX5ITfWH zQ7_d!vn6yJ(-Z|1?|KiY-Z%dw>v&@RUH|D?`iBjF^f?+-S#QoUV`~~Yw&y)&jK%v{hHOCVNU`> zdvl+Z6hEK6oz44(;Braoh1hs1&&Ro^^!0W_+5H>2NsT`v;Wcz%;c1^Mi#=+S4xlbh3OK6R!+EUf7?bZ*;H3# zEYLsUFL9*|Xp7d9xGUvz@YPKOh4^j|o2wD7nNt~MI^P>c#(Z58l>`^Da8}huzX+WhQ1Zi)%ftS@m#6Cq87;H+efTk$bkFsmc}_Rif9o(a8uzz=(6& z-rM`W?OrH&(Kpg7`OC)vjln8m#dBDzD`IsgdXBqS;IEBM4He|Qa`bcRc6QuGq)U!! zeU$>|#%d6)x1(vB=FnmE6VGqDrH;3=9O?UIYI_;JTt7PcMKfb*V59oBQ+jmsjfr$5 z(LlEn?%J{IY}r)Bbj(9~Y*hBr{mCWDrW^^9qmTp-e6p0^(9*2n1Kw~Ujm0f*se-qU zE%C%Tl&AU_6W}i2yyNG&Tn}00aCM(`^|TRS1;7i2A(aRi~gc!I<}kt(d&!x)~P#k z;+=HCYtBOh`_uxW70bH1TRm5M-&@t-ajnDM+B|ksA#1SAw>ECEa?vli?>H^eBp%tB zbfq~bF=I6M{d#yNJHBuwX|FQaDxw0A-Yoq*m2h4C-3=$ytO{yUd z(f)gJ%o)d zTH;ZJGv+KEw>>%>$HZ1sOU$}jr)EOsqae?>D - - - - - - - - - ёRadio - Player - - - -
- - -
-
-
 
-
 
-
-
-
-
-
-
-
-
-
- -
-
WebSD
- -
- -
-
volume: 0
-
bitrate: 0kBit
-
rssi: 0dBm
-
-
    -
-
-
- -
-
powered by ёRadio | v%VERSION%
-
- - - - diff --git a/yoRadio/data/www/ir.css.gz b/yoRadio/data/www/ir.css.gz index c901046486520510f1a7f508b3d4748dcdae969f..eb74a489715bb08d7390e15e4676f55594b3851c 100644 GIT binary patch literal 1326 zcmV+}1=0E+iwFP!000001D#iGbJ{o%{+?f4YkIqJ;K9Hb=SawL}!Xwxq@ zvMr2?Y`L-wq@Dctll+Ed>_D0sg1r{2)jrQYyKZ1Mr_2Lq3+y<^2S1MhaBvt9_-q27 z`sn=V<>*Y_BDQ8Qh!@NW+L+Dr;!fSEHj{K$k)`UA@(T4Fr`Mz8@PB}q^gw3jZUksohLcYfqb-{OQPiQkPD z;vd*|&1`F7l1~EYII+2D$Ph%L@ixharZxrx#AtYMqph*S7ba-;(o=bmx!5;>4q(J- zx``EWP7|=_0ugNvJxs(_*NChj$2L3#eTE@91rz9p(oO2N(@wlD5Ox=QdtXlJABUv0 zrKGerOL2ta5fXmW?PAk9jlrTM_Mjl)LF{V_lE8EF8fNiI%Pp+j$$Tw)YeBIi7RoIG ziZfFbiX(-Hh$Iv$E5{;SxiKDTqBBy?F(EZ)0wCm!E>VTIGmAt?J?);lVRYL)__2Um z_Mp}3bS=0ymBoD+a_Y8mT20H)E4D$M7HpxnY-29y3b9kLH9*0n6)ITH5=%`m$qvw# z02L{r1Xi=?RkG{^DRJBlv}8ToT9X9=!9LP{wT~Svq=lq6dqs&(v(e&W_~74ssdUS4p)Vk`UmWry=CDe)mqr6f46M~7uOj!pXflwLMoP)fIiYJ4Brgc1G1JJ- zP}PluGzE-uDw2}GE7x!)gi!V~6GTCPm<>a;lLVur;knSLjYTi%Rt%yt3B0+%?@&ZI z-!?WS$aYViuscbC@9WGl$(wp1ZFMQBY{o?%q*QtRcv+djp!!QI1J zzqxX0U;N!priC@kf@!%FeT@J=yiSU2bpA3yr z{|R6G)3@DAdx863F8bG#xz-Dy~o@3hWh(9`u*C_ZHWB>pF literal 1235 zcmV;^1T6a>iwFqN)5&5018H(DV{>x=jaO}N+By{e&abdmU9Ht^x)5HV`Jjw!avcj&5Lh!2vfQ#dZ zz#ldUX^75RFRcU27z!vy`m)ckdnN?(*Wf4+QjQFVk|YRY8?-&9KEd|r==FNQinbu8B=cbjowd(s5~en&+|%yMclOxUi1AMx z`nJ+6L~BtiV5A4?5tQzR1pA?ZMX16j2ZbD^k;!GDL0$%MYizK~ zS2pMla;F2xd>q=q1Tf(=H?mAPr&+o^8gj#f0VcxK6(Y}&V+S6CA;XXygBc8CsU}z3 z>tUBu-tT7Yv?gO6En|&INgWbPNT|uRr=m@6a!E<5K_%MryoM5(rYToA+HxaJ zUNvn5hsY?x$dlzHES8T(6svtnEL@8bK@Kk=S?2I$Nsn4thV~^k zVYs?6j$rt9Vs`MCw@#;@xu^k833vLZXa03or2rhJPb~>`)Y8Ho^N@cV$ z^VTFO>noI$oUJ+29q0$1Uez}?jO?xZVz11 zZ~tR4n-3%^#nn!uzcykDwvq6Z=e**$r&(*O0@WO9>N;8TBxm|GU&UOm*^m|8fy6l! ztqT55N6%53-7>N1r97}d9vWiTQC?byAjqoI!P?;jbzjrCAYtV2y$dOZ=)WA!#@1x`gwOvQI{t;T!o$b&;ni$CzM%8({$=n9`sU?ja5ou#`!boV$>Ys= z+mxz@v-#ro{ - - - - - - - - - - ёRadio - IR Recorder - - - -
-

IR Recorder

-
-
-
-
-
-
-
1
2
3
-
4
5
6
-
7
8
9
-
*
0
#
-
-
-

Welcome to IR Recorder!

- Press the button on the left
to record the code. - DONE -
- -
-
-
-
powered by ёRadio | v%VERSION%
-
- - diff --git a/yoRadio/data/www/ir.js.gz b/yoRadio/data/www/ir.js.gz index 6a85b008b6fda14d4d6e45c7dcf93d44c3161cde..0addc3d2d62b3d45a18ba30764177215eb8ba876 100644 GIT binary patch literal 1026 zcmV+d1pWITiwFP!000001I1TeZyGriedkxWsOrpwW*{&7kjZqlMUl3vw2_jm`p~UZ zl%hbJ+CP`b*NWPHPxx$!1`RM-56bVKB&`d}H_=Y!5vndG|+m|3LdzVm z*$ts{X@eL~w4j^O}NXy-2J;dLYnt3AXW+KgJ1+Kg*gI-`anlz;ATKg0{F%EYmK?*j92XvZ;EOlA;SKSDCemUC-10dt*$ z9lm{hmxaMXNh6uegDB=$r+R>|CUyShOyUCA)ZiU8rr#4!zkM9$RO=5Y-LT7*0wz_q zqWKcKkq2cgn?oS5?qB2Qe{IeA(-HwDyN!N`p`QbIfc4E9e+0Hk1n;b}16J z!W2>ILrBx5MimUc2E7I~v61&ip?1TIKO%hicd-C9q{wJduKkS^&{_Go>6CvrEus;m zF4F%do~$v3uo>%;5Pnkgh;QBu4kHOo4M1vb0Km<;<-sr@5~r5Tr=QtQm7GoJa5c?!e(WvE~-S5S*E*<+2n6o*BThYI1- z;E*)!?UAObnQ|R@s3}hhp<0}dG&}nuP5lSrPy2LPxeuIH5Ph8$zaZ_DIQtA>cETcx zR%KD6eQOZdr97aZ=l(mN;~H9btGjYFS{h?JH)pd`_2om<0-I9pQ58%-*{w>akr7Un z=NG5Q@)%Jf%P;B@U%etN<#^$^YHH!MT*{n3V!m2*!%dD^J^g<_yuU##!QJ)nzd$>H zo;Px(7gW3ndXB2fwijIW{X}wDHcYgOe9E&7M2Y-~7}`)}_5^YoZAaN!(j66(cF%Gg z)*bRV9DCBA0Ae2-o0Ikq+1ZgOeodPL?g;(cdnY}*jYbsOFTuzfy?qti?W~G z^NX#MCRamyCdZcVc!m7*ZoIv`&m#$zE0n}Bb@@-Utq6_&GI-*^wTCdUr&apO18H(DYI6X^S6y$@Fcf|7uP_x_5|yRh3lDSwv1$^a0TLVH z0g!N=+tzAoSGL=3LjCVt+xcwEXuD1HVRPd9b&ij3>?KuXObx8)9ZATqm44OjKL5Sq zB9*H+lZ+ZJMLdz(2s(pxccp*zTT66W!B9&!1(QE&P>KnIL3+g-!)G8DXwb^z(KNkW zf-qNH8xWwvAd@r=UJxm+a1f#8Xd#$QNx0zV8w{^qjxZv>TZFI-sJih{!!ka);gl3w zW`HG+!{A2UaWN)F5;+G!C@BM3I{_|39LIrkEsMj+kpm!T|YShF=UK@ql4bNUi`0#Z;2Q{F`XkM=U4HeL7@wjdkf7cD7 z5v0!3|0kZTF@~@itCA3Yzv281 z;JoW6`uk*=<{eN^nZERVD(yU9I0+c;BlHL#~|Z268? z$d2#Eo6Gw+l3P;oN_!AZ!my25iq#j K+;9V3L$qNw($D$Z~%HUgu(&YA`m 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 z zU#>3SvwWRT9JQ+{XAtoW~%c$%vl|DewRt}@^=3@ zSnu19<)JLt<}-W9*qA8)zJYq;L%_C&@(I#M-|xG3tJQPWZ;zW0+-FtFD3Yts?IA0w zb``Au_0RYC^sve%{yvnTFcweC$TLYQP0wx(DmO!1oP;!2OT(7wQq5 zKSD{H$#fNmEp`Pgqq^oX2>Va{A6S@o17S_SgL@2$_UHN+nl+;Bf@*awd)+Fo0EACY zyq`Wf@ouEQ+Y4lnP1ipZ#WzeXN-*O4a@P*!H_Yyin_UHx|1FzMznYtzsnN!ly<^V$ MH@Cha)PyJi09N?K+yDRo literal 0 HcmV?d00001 diff --git a/yoRadio/data/www/script.js.gz b/yoRadio/data/www/script.js.gz index 7b1037315a8f1b3a42c90bb60710a30a17a96e48..656b931aa7de430867d71b38d907941c8608d0f3 100644 GIT binary patch literal 7106 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 literal 5965 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 diff --git a/yoRadio/data/www/settings.css.gz b/yoRadio/data/www/settings.css.gz deleted file mode 100644 index 40da547eaea60ed62a0d95ef85fd8b071821512c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2454 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 U3SXjw*^kfv1Crv47seI<0Jv-Bu>b%7 diff --git a/yoRadio/data/www/settings.html b/yoRadio/data/www/settings.html deleted file mode 100644 index edd2560..0000000 --- a/yoRadio/data/www/settings.html +++ /dev/null @@ -1,261 +0,0 @@ - - - - - - - - - - - ёRadio - Settings - - - -

-

SёTTINGS

- -
-
- - - - - - -
 
-
-
- -
powered by ёRadio | v%VERSION%
-
- - diff --git a/yoRadio/data/www/style.css.gz b/yoRadio/data/www/style.css.gz index 01bbd1a69bb93877860503227059bad02bf7761f..210bbf3826f2f52f605e145d7c893b9fc4952a30 100644 GIT binary patch literal 4382 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 Yi5uF;INceIB(#J71M-{;tOiN|02C693jhEB literal 7442 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 Q8Uw}kpWLPbeOOrl07+iW;s5{u diff --git a/yoRadio/data/www/theme.css b/yoRadio/data/www/theme.css new file mode 100644 index 0000000..185a6c4 --- /dev/null +++ b/yoRadio/data/www/theme.css @@ -0,0 +1,16 @@ +:root { +--main-bg-color: #010101; +--main-text-color: #cccccc; +--main-hl-color: #ffffff; +--odd-bg-color: #272727; +--accent-color: #e3d25f; +--accent-dark: #ad9838; +--accent-text-color: #000000; +--input-border: #2d2d2d; +--logo: #e3d25f; +--logo-red: #ff0000; +--logo-shadow: #a89c46; +--playlist-hover: #323232; +--section-gradient: #111111; +--section-border: #555555; +} diff --git a/yoRadio/data/www/update.html b/yoRadio/data/www/update.html deleted file mode 100644 index a522f3f..0000000 --- a/yoRadio/data/www/update.html +++ /dev/null @@ -1,38 +0,0 @@ - - - - - - - - - - ёRadio - Update - - - -
- -
-
-
Please choose firmware or SPIFFS *.bin file
-
-
- - -
-
- - -
-
- - Cancel -
-
-
powered by ёRadio | v%VERSION%
-
- - - diff --git a/yoRadio/data/www/updform.html.gz b/yoRadio/data/www/updform.html.gz new file mode 100644 index 0000000000000000000000000000000000000000..4206d1725b0e78e78672794bffadfa429f6a65c1 GIT binary patch literal 572 zcmV-C0>k|uiwFqcv~Xwu19fm@W^ZzBE@*UZYyh2<&5qk35XbL*iYZd1wyNW7E-P(q zUshVFr$$YCUX3vhC>RjnIDU*iTHmPPul0U(wdx@X%)p=D41Wv&kX7OgqRNTXM@@iA zbS_LBDc(U$ry)NL=aoic&unMW5OBViEGG?Kl1@~f-@w&&`{66BCzI4lp*2!t^~cEX+7YIXN07qSvdCLwH{>xrsY zq{xIat%vapi@vmvOR#Xal%1Nci&_~aO z`$S$TEgLMhnj5Q+mN~aF?;HvS#!F7Z<5^C=4nr=gimA}ldEH74fm>DwkFT(SOR`eG zr>H2C_fvVr?J&(!T%PzqoV`zy@hg!e>+i@zJih!TH$P~qO-~A=J7$Ax%RVBFe#yyw zDN&usgvh-&?j}u-!t=J=P~D_#x83g2UJoWrN%80Rk2s2KqqX7*XJ(y<;FGJS2LA;< K=x;#@1pol?au{9! literal 0 HcmV?d00001 diff --git a/yoRadio/src/audioI2S/Audio.cpp b/yoRadio/src/audioI2S/Audio.cpp index 8e82bfe..f98fdf1 100644 --- a/yoRadio/src/audioI2S/Audio.cpp +++ b/yoRadio/src/audioI2S/Audio.cpp @@ -3604,15 +3604,27 @@ void Audio::playAudioData(){ } //--------------------------------------------------------------------------------------------------------------------- bool Audio::parseHttpResponseHeader() { // this is the response to a GET / request - + static uint32_t notavailablefor = 0; if(getDatamode() != HTTP_RESPONSE_HEADER) return false; - if(_client->available() == 0) return false; - + if(_client->available() == 0) { + if (notavailablefor == 0) notavailablefor = millis(); + if (millis() - notavailablefor > HEADER_TIMEOUT) { + notavailablefor = 0; + if(audio_showstation) audio_showstation(""); + if(audio_icydescription) audio_icydescription(""); + if(audio_icyurl) audio_icyurl(""); + AUDIO_ERROR("Host %s not available", m_lastHost); + m_lastHost[0] = '\0'; + setDatamode(AUDIO_NONE); + stopSong(); + } + return false; + } + notavailablefor = 0; char rhl[512]; // responseHeaderline bool ct_seen = false; uint32_t ctime = millis(); uint32_t timeout = 2500; // ms - while(true){ // outer while uint16_t pos = 0; if((millis() - ctime) > timeout) { diff --git a/yoRadio/src/audioI2S/AudioEx.h b/yoRadio/src/audioI2S/AudioEx.h index c25184c..448d23e 100644 --- a/yoRadio/src/audioI2S/AudioEx.h +++ b/yoRadio/src/audioI2S/AudioEx.h @@ -36,6 +36,10 @@ #define AUDIOBUFFER_MULTIPLIER2 8 #endif +#ifndef HEADER_TIMEOUT +#define HEADER_TIMEOUT 5000 +#endif + #if ESP_ARDUINO_VERSION >= ESP_ARDUINO_VERSION_VAL(3, 0, 0) #include "hal/gpio_ll.h" #endif diff --git a/yoRadio/src/core/config.cpp b/yoRadio/src/core/config.cpp index 0f1cfdc..f478000 100644 --- a/yoRadio/src/core/config.cpp +++ b/yoRadio/src/core/config.cpp @@ -18,14 +18,22 @@ void u8fix(char *src){ } bool Config::_isFSempty() { - const char* reqiredFiles[] = {"dragpl.js.gz","elogo.png","elogo84.png","index.html", - "ir.css.gz","ir.html","ir.js.gz","script.js.gz", - "settings.css.gz","settings.html","style.css.gz","update.html"}; - const uint8_t reqiredFilesSize = 12; + const char* reqiredFiles[] = {"dragpl.js.gz","ir.css.gz","irrecord.html.gz","ir.js.gz","logo.svg.gz","options.html.gz","player.html.gz","script.js.gz", + "style.css.gz","updform.html.gz","theme.css"}; + const uint8_t reqiredFilesSize = 11; char fullpath[28]; + if(SPIFFS.exists("/www/settings.html")) SPIFFS.remove("/www/settings.html"); + if(SPIFFS.exists("/www/update.html")) SPIFFS.remove("/www/update.html"); + if(SPIFFS.exists("/www/index.html")) SPIFFS.remove("/www/index.html"); + if(SPIFFS.exists("/www/ir.html")) SPIFFS.remove("/www/ir.html"); + if(SPIFFS.exists("/www/elogo.png")) SPIFFS.remove("/www/elogo.png"); + if(SPIFFS.exists("/www/elogo84.png")) SPIFFS.remove("/www/elogo84.png"); for (uint8_t i=0; iexists(INDEX_SD_PATH)) { File index = SDPLFS()->open(INDEX_SD_PATH, "r"); - store.countStation = index.size() / 4; + //store.countStation = index.size() / 4; if(doIndex){ lastStation(_randomStation()); sdResumePos = 0; } index.close(); - saveValue(&store.countStation, store.countStation, true, true); + //saveValue(&store.countStation, store.countStation, true, true); } } @@ -190,6 +200,7 @@ bool Config::spiffsCleanup(){ void Config::initPlaylistMode(){ uint16_t _lastStation = 0; + uint16_t cs = playlistLength(); #ifdef USE_SD if(getMode()==PM_SDCARD){ if(!sdman.start()){ @@ -203,7 +214,8 @@ void Config::initPlaylistMode(){ initSDPlaylist(); if(_bootDone) Serial.println("done"); else BOOTLOG("done"); _lastStation = store.lastSdStation; - if(_lastStation>store.countStation && store.countStation>0){ + + if(_lastStation>cs && cs>0){ _lastStation=1; } if(_lastStation==0) { @@ -220,7 +232,7 @@ void Config::initPlaylistMode(){ #endif if(getMode()==PM_WEB && !emptyFS) initPlaylist(); log_i("%d" ,_lastStation); - if (_lastStation == 0 && store.countStation > 0) { + if (_lastStation == 0 && cs > 0) { _lastStation = getMode()==PM_WEB?1:_randomStation(); } lastStation(_lastStation); @@ -467,28 +479,37 @@ void Config::indexPlaylist() { } void Config::initPlaylist() { - store.countStation = 0; + //store.countStation = 0; if (!SPIFFS.exists(INDEX_PATH)) indexPlaylist(); - if (SPIFFS.exists(INDEX_PATH)) { + /*if (SPIFFS.exists(INDEX_PATH)) { File index = SPIFFS.open(INDEX_PATH, "r"); store.countStation = index.size() / 4; index.close(); saveValue(&store.countStation, store.countStation, true, true); - } + }*/ } - -void Config::loadStation(uint16_t ls) { +uint16_t Config::playlistLength(){ + uint16_t out = 0; + if (SDPLFS()->exists(REAL_INDEX)) { + File index = SDPLFS()->open(REAL_INDEX, "r"); + out = index.size() / 4; + index.close(); + } + return out; +} +bool Config::loadStation(uint16_t ls) { char sName[BUFLEN], sUrl[BUFLEN]; int sOvol; - if (store.countStation == 0) { + uint16_t cs = playlistLength(); + if (cs == 0) { memset(station.url, 0, BUFLEN); memset(station.name, 0, BUFLEN); strncpy(station.name, "ёRadio", BUFLEN); station.ovol = 0; - return; + return false; } - if (ls > store.countStation) { + if (ls > playlistLength()) { ls = 1; } File playlist = SDPLFS()->open(REAL_PLAYL, "r"); @@ -507,6 +528,7 @@ void Config::loadStation(uint16_t ls) { setLastStation(ls); } playlist.close(); + return true; } char * Config::stationByNum(uint16_t num){ @@ -527,7 +549,7 @@ uint8_t Config::fillPlMenu(int from, uint8_t count, bool fromNextion) { int ls = from; uint8_t c = 0; bool finded = false; - if (store.countStation == 0) { + if (playlistLength() == 0) { return 0; } File playlist = SDPLFS()->open(REAL_PLAYL, "r"); @@ -569,6 +591,19 @@ uint8_t Config::fillPlMenu(int from, uint8_t count, bool fromNextion) { return c; } +void Config::escapeQuotes(const char* input, char* output, size_t maxLen) { + size_t j = 0; + for (size_t i = 0; input[i] != '\0' && j < maxLen - 1; ++i) { + if (input[i] == '"' && j < maxLen - 2) { + output[j++] = '\\'; + output[j++] = '"'; + } else { + output[j++] = input[i]; + } + } + output[j] = '\0'; +} + bool Config::parseCSV(const char* line, char* name, char* url, int &ovol) { char *tmpe; const char* cursor = line; diff --git a/yoRadio/src/core/config.h b/yoRadio/src/core/config.h index 74bf37c..6c564ff 100644 --- a/yoRadio/src/core/config.h +++ b/yoRadio/src/core/config.h @@ -204,11 +204,12 @@ class Config { uint8_t setLastSSID(uint8_t val); void setTitle(const char* title); void setStation(const char* station); + void escapeQuotes(const char* input, char* output, size_t maxLen); bool parseCSV(const char* line, char* name, char* url, int &ovol); bool parseJSON(const char* line, char* name, char* url, int &ovol); bool parseWsCommand(const char* line, char* cmd, char* val, uint8_t cSize); bool parseSsid(const char* line, char* ssid, char* pass); - void loadStation(uint16_t station); + bool loadStation(uint16_t station); bool initNetwork(); bool saveWifi(); bool saveWifiFromNextion(const char* post); @@ -220,6 +221,7 @@ class Config { void initSDPlaylist(); void changeMode(int newmode=-1); #endif + uint16_t playlistLength(); uint16_t lastStation(){ return getMode()==PM_WEB?store.lastStation:store.lastSdStation; } diff --git a/yoRadio/src/core/controls.cpp b/yoRadio/src/core/controls.cpp index fb82302..7eb5803 100644 --- a/yoRadio/src/core/controls.cpp +++ b/yoRadio/src/core/controls.cpp @@ -223,7 +223,7 @@ void irNumber(uint8_t num) { display.putRequest(NEWMODE, NUMBERS); if (display.numOfNextStation > UINT16_MAX / 10) return; s = display.numOfNextStation * 10 + num; - if (s > config.store.countStation) return; + if (s > config.playlistLength()) return; display.numOfNextStation = s; display.putRequest(NEXTSTATION, s); } @@ -464,8 +464,9 @@ void controlsEvent(bool toRight, int8_t volDelta) { if (display.mode() == STATIONS) { display.resetQueue(); int p = toRight ? display.currentPlItem + 1 : display.currentPlItem - 1; - if (p < 1) p = config.store.countStation; - if (p > config.store.countStation) p = 1; + uint16_t cs = config.playlistLength(); + if (p < 1) p = cs; + if (p > cs) p = 1; display.currentPlItem = p; display.putRequest(DRAWPLAYLIST, p); } diff --git a/yoRadio/src/core/mqtt.cpp b/yoRadio/src/core/mqtt.cpp index a1180a3..497c83a 100644 --- a/yoRadio/src/core/mqtt.cpp +++ b/yoRadio/src/core/mqtt.cpp @@ -39,7 +39,11 @@ void mqttPublishStatus() { memset(topic, 0, 140); memset(status, 0, BUFLEN*3); sprintf(topic, "%s%s", MQTT_ROOT_TOPIC, "status"); - sprintf(status, "{\"status\": %d, \"station\": %d, \"name\": \"%s\", \"title\": \"%s\", \"on\": %d}", player.status()==PLAYING?1:0, config.lastStation(), config.station.name, config.station.title, config.store.dspon); + char name[BUFLEN*2]; + char title[BUFLEN*2]; + config.escapeQuotes(config.station.name, name, sizeof(name)); + config.escapeQuotes(config.station.title, title, sizeof(name)); + sprintf(status, "{\"status\": %d, \"station\": %d, \"name\": \"%s\", \"title\": \"%s\", \"on\": %d}", player.status()==PLAYING?1:0, config.lastStation(), name, title, config.store.dspon); mqttClient.publish(topic, 0, true, status); } } @@ -131,7 +135,8 @@ void onMqttMessage(char* topic, char* payload, AsyncMqttClientMessageProperties int sb; if (sscanf(buf, "play %d", &sb) == 1 ) { if (sb < 1) sb = 1; - if (sb >= config.store.countStation) sb = config.store.countStation; + uint16_t cs = config.playlistLength(); + if (sb >= cs) sb = cs; player.sendCommand({PR_PLAY, (uint16_t)sb}); return; } diff --git a/yoRadio/src/core/netserver.cpp b/yoRadio/src/core/netserver.cpp index 0ec3c36..c11a543 100644 --- a/yoRadio/src/core/netserver.cpp +++ b/yoRadio/src/core/netserver.cpp @@ -21,7 +21,7 @@ #define NSQ_SEND_DELAY (TickType_t)100 //portMAX_DELAY? #endif -//#define CORS_DEBUG +//#define CORS_DEBUG //Enable CORS policy: 'Access-Control-Allow-Origin' (for testing) NetServer netserver; @@ -61,8 +61,10 @@ bool NetServer::begin(bool quiet) { irRecordEnable = false; nsQueue = xQueueCreate( 20, sizeof( nsRequestParams_t ) ); while(nsQueue==NULL){;} + if(config.emptyFS){ - webserver.on("/", HTTP_GET, [](AsyncWebServerRequest * request) { request->send_P(200, "text/html", emptyfs_html, processor); }); + webserver.on("/", HTTP_GET, [](AsyncWebServerRequest * request) { request->send_P(200, "text/html", emptyfs_html); }); + webserver.on("/webboard", HTTP_POST, [](AsyncWebServerRequest *request) { request->redirect("/"); ESP.restart(); }, handleUploadWeb); webserver.on("/", HTTP_POST, [](AsyncWebServerRequest *request) { if(request->arg("ssid")!="" && request->arg("pass")!=""){ char buf[BUFLEN]; @@ -73,11 +75,14 @@ bool NetServer::begin(bool quiet) { return; } request->redirect("/"); - ESP.restart(); + ESP.restart(); }, handleUploadWeb); }else{ webserver.on("/", HTTP_ANY, handleHTTPArgs); - webserver.on("/webboard", HTTP_GET, [](AsyncWebServerRequest * request) { request->send_P(200, "text/html", emptyfs_html, processor); }); + webserver.on("/settings.html", HTTP_GET, handleHTTPArgs); + webserver.on("/update.html", HTTP_GET, handleHTTPArgs); + webserver.on("/ir.html", HTTP_GET, handleHTTPArgs); + webserver.on("/webboard", HTTP_GET, [](AsyncWebServerRequest * request) { request->send_P(200, "text/html", emptyfs_html); }); webserver.on("/webboard", HTTP_POST, [](AsyncWebServerRequest *request) { request->redirect("/"); }, handleUploadWeb); } @@ -90,8 +95,13 @@ bool NetServer::begin(bool quiet) { webserver.on("/upload", HTTP_POST, beginUpload, handleUpload); webserver.on("/update", HTTP_GET, handleHTTPArgs); webserver.on("/update", HTTP_POST, beginUpdate, handleUpdate); - webserver.on("/settings", HTTP_GET, handleHTTPArgs); - if (IR_PIN != 255) webserver.on("/ir", HTTP_GET, handleHTTPArgs); + + webserver.on("/variables.js", HTTP_GET, [](AsyncWebServerRequest * request) { + char varjsbuf[BUFLEN]; + sprintf (varjsbuf, "var yoVersion='%s';\nvar formAction='%s';\nvar playMode='%s';\n", YOVERSION, (network.status == CONNECTED && !config.emptyFS)?"webboard":"", (network.status == CONNECTED)?"player":"ap"); + request->send(200, "text/html", varjsbuf); + }); + webserver.serveStatic("/", SPIFFS, "/www/").setCacheControl("max-age=31536000"); #ifdef CORS_DEBUG DefaultHeaders::Instance().addHeader(F("Access-Control-Allow-Origin"), F("*")); @@ -275,7 +285,7 @@ void NetServer::processQueue(){ sprintf (wsbuf, "{\"act\":[%s]}", act.c_str()); break; } - case GETMODE: sprintf (wsbuf, "{\"pmode\":\"%s\"}", network.status == CONNECTED ? "player" : "ap"); break; + //case STARTUP: sprintf (wsbuf, "{\"command\":\"startup\", \"payload\": {\"mode\":\"%s\", \"version\":\"%s\"}}", network.status == CONNECTED ? "player" : "ap", YOVERSION); break; case GETINDEX: { requestOnChange(STATION, clientId); requestOnChange(TITLE, clientId); @@ -334,11 +344,11 @@ void NetServer::processQueue(){ break; case DSPON: sprintf (wsbuf, "{\"dspontrue\":%d}", 1); break; case STATION: requestOnChange(STATIONNAME, clientId); requestOnChange(ITEM, clientId); break; - case STATIONNAME: sprintf (wsbuf, "{\"nameset\": \"%s\"}", config.station.name); break; + case STATIONNAME: sprintf (wsbuf, "{\"payload\":[{\"id\":\"nameset\", \"value\": \"%s\"}]}", config.station.name); break; case ITEM: sprintf (wsbuf, "{\"current\": %d}", config.lastStation()); break; - case TITLE: sprintf (wsbuf, "{\"meta\": \"%s\"}", config.station.title); telnet.printf("##CLI.META#: %s\n> ", config.station.title); break; - case VOLUME: sprintf (wsbuf, "{\"vol\": %d}", config.store.volume); telnet.printf("##CLI.VOL#: %d\n", config.store.volume); break; - case NRSSI: sprintf (wsbuf, "{\"rssi\": %d}", rssi); /*rssi = 255;*/ break; + case TITLE: sprintf (wsbuf, "{\"payload\":[{\"id\":\"meta\", \"value\": \"%s\"}]}", config.station.title); telnet.printf("##CLI.META#: %s\n> ", config.station.title); break; + case VOLUME: sprintf (wsbuf, "{\"payload\":[{\"id\":\"volume\", \"value\": %d}]}", config.store.volume); telnet.printf("##CLI.VOL#: %d\n", config.store.volume); break; + case NRSSI: sprintf (wsbuf, "{\"payload\":[{\"id\":\"rssi\", \"value\": %d}]}", rssi); /*rssi = 255;*/ break; case SDPOS: sprintf (wsbuf, "{\"sdpos\": %d,\"sdend\": %d,\"sdtpos\": %d,\"sdtend\": %d}", player.getFilePos(), player.getFileSize(), @@ -347,10 +357,10 @@ void NetServer::processQueue(){ break; case SDLEN: sprintf (wsbuf, "{\"sdmin\": %d,\"sdmax\": %d}", player.sd_min, player.sd_max); break; case SDSNUFFLE: sprintf (wsbuf, "{\"snuffle\": %d}", config.store.sdsnuffle); break; - case BITRATE: sprintf (wsbuf, "{\"bitrate\": %d, \"format\": \"%s\"}", config.station.bitrate, getFormat(config.configFmt)); break; - case MODE: sprintf (wsbuf, "{\"mode\": \"%s\"}", player.status() == PLAYING ? "playing" : "stopped"); telnet.info(); break; - case EQUALIZER: sprintf (wsbuf, "{\"bass\": %d, \"middle\": %d, \"trebble\": %d}", config.store.bass, config.store.middle, config.store.trebble); break; - case BALANCE: sprintf (wsbuf, "{\"balance\": %d}", config.store.balance); break; + case BITRATE: sprintf (wsbuf, "{\"payload\":[{\"id\":\"bitrate\", \"value\": %d}, {\"id\":\"fmt\", \"value\": \"%s\"}]}", config.station.bitrate, getFormat(config.configFmt)); break; + case MODE: sprintf (wsbuf, "{\"payload\":[{\"id\":\"playerwrap\", \"value\": \"%s\"}]}", player.status() == PLAYING ? "playing" : "stopped"); telnet.info(); break; + case EQUALIZER: sprintf (wsbuf, "{\"payload\":[{\"id\":\"bass\", \"value\": %d}, {\"id\": \"middle\", \"value\": %d}, {\"id\": \"trebble\", \"value\": %d}]}", config.store.bass, config.store.middle, config.store.trebble); break; + case BALANCE: sprintf (wsbuf, "{\"payload\":[{\"id\": \"balance\", \"value\": %d}]}", config.store.balance); break; case SDINIT: sprintf (wsbuf, "{\"sdinit\": %d}", SDC_CS!=255); break; case GETPLAYERMODE: sprintf (wsbuf, "{\"playermode\": \"%s\"}", config.getMode()==PM_SDCARD?"modesd":"modeweb"); break; #ifdef USE_SD @@ -405,7 +415,7 @@ void NetServer::onWsMessage(void *arg, uint8_t *data, size_t len, uint8_t client data[len] = 0; char cmd[65], val[65]; if (config.parseWsCommand((const char*)data, cmd, val, 65)) { - if (strcmp(cmd, "getmode") == 0 ) { requestOnChange(GETMODE, clientId); return; } + //if (strcmp(cmd, "getmode") == 0 ) { requestOnChange(GETMODE, clientId); return; } if (strcmp(cmd, "getindex") == 0 ) { requestOnChange(GETINDEX, clientId); return; } if (strcmp(cmd, "getsystem") == 0 ) { requestOnChange(GETSYSTEM, clientId); return; } if (strcmp(cmd, "getscreen") == 0 ) { requestOnChange(GETSCREEN, clientId); return; } @@ -433,6 +443,12 @@ void NetServer::onWsMessage(void *arg, uint8_t *data, size_t len, uint8_t client display.putRequest(SHOWVUMETER); return; } + if (strcmp(cmd, "prev") == 0) { player.prev(); return; } + if (strcmp(cmd, "toggle") == 0) { player.toggle(); return; } + if (strcmp(cmd, "next") == 0) { player.next(); return; } + if (strcmp(cmd, "volm") == 0) { player.stepVol(false); return; } + if (strcmp(cmd, "volp") == 0) { player.stepVol(true); return; } + if (strcmp(cmd, "play") == 0) { uint16_t valb = atoi(val); player.sendCommand({PR_PLAY, valb}); return; } if (strcmp(cmd, "softap") == 0) { uint8_t valb = atoi(val); config.saveValue(&config.store.softapdelay, valb); @@ -718,7 +734,7 @@ void NetServer::onWsMessage(void *arg, uint8_t *data, size_t len, uint8_t client netserver.requestOnChange(BALANCE, 0); return; } - if (strcmp(cmd, "treble") == 0) { + if (strcmp(cmd, "trebble") == 0) { int8_t valb = atoi(val); player.setTone(config.store.bass, config.store.middle, valb); config.setTone(config.store.bass, config.store.middle, valb); @@ -739,6 +755,19 @@ void NetServer::onWsMessage(void *arg, uint8_t *data, size_t len, uint8_t client netserver.requestOnChange(EQUALIZER, 0); return; } + if (strcmp(cmd, "reboot") == 0) { + ESP.restart(); + return; + } + if (strcmp(cmd, "format") == 0) { + SPIFFS.format(); + ESP.restart(); + return; + } + if (strcmp(cmd, "reset") == 0) { + config.reset(); + return; + } if (strcmp(cmd, "submitplaylist") == 0) { return; } @@ -884,7 +913,7 @@ void handleUploadWeb(AsyncWebServerRequest *request, String filename, size_t ind void onWsEvent(AsyncWebSocket *server, AsyncWebSocketClient *client, AwsEventType type, void *arg, uint8_t *data, size_t len) { switch (type) { - case WS_EVT_CONNECT: if (config.store.audioinfo) Serial.printf("[WEBSOCKET] client #%u connected from %s\n", client->id(), client->remoteIP().toString().c_str()); break; + case WS_EVT_CONNECT: /*netserver.requestOnChange(STARTUP, client->id()); */if (config.store.audioinfo) Serial.printf("[WEBSOCKET] client #%u connected from %s\n", client->id(), client->remoteIP().toString().c_str()); break; case WS_EVT_DISCONNECT: if (config.store.audioinfo) Serial.printf("[WEBSOCKET] client #%u disconnected\n", client->id()); break; case WS_EVT_DATA: netserver.onWsMessage(arg, data, len, client->id()); break; case WS_EVT_PONG: @@ -912,17 +941,21 @@ void handleHTTPArgs(AsyncWebServerRequest * request) { } return; } + Serial.println(request->url()); if (strcmp(request->url().c_str(), "/") == 0 && request->params() == 0) { - netserver.chunkedHtmlPage(String(), request, network.status == CONNECTED ? "/www/index.html" : "/www/settings.html"); - return; - } - if (strcmp(request->url().c_str(), "/update") == 0 || strcmp(request->url().c_str(), "/settings") == 0 || strcmp(request->url().c_str(), "/ir") == 0) { - char buf[40] = { 0 }; - sprintf(buf, "/www%s.html", request->url().c_str()); - netserver.chunkedHtmlPage(String(), request, buf); + if(network.status == CONNECTED){ + request->send_P(200, "text/html", index_html); + }else{ + request->redirect("/settings.html"); + } + //netserver.chunkedHtmlPage(String(), request, network.status == CONNECTED ? "/www/index.html" : "/www/settings.html", false); return; } } + if (strcmp(request->url().c_str(), "/settings.html") == 0 || strcmp(request->url().c_str(), "/update.html") == 0 || strcmp(request->url().c_str(), "/ir.html") == 0){ + request->send_P(200, "text/html", index_html); + return; + } if (network.status == CONNECTED) { bool commandFound=false; if (request->hasArg("start")) { player.sendCommand({PR_PLAY, config.lastStation()}); commandFound=true; } @@ -969,7 +1002,8 @@ void handleHTTPArgs(AsyncWebServerRequest * request) { AsyncWebParameter* p = request->getParam(request->hasArg("playstation") ? "playstation" : "play", request->method() == HTTP_POST); int id = atoi(p->value().c_str()); if (id < 1) id = 1; - if (id > config.store.countStation) id = config.store.countStation; + uint16_t cs = config.playlistLength(); + if (id > cs) id = cs; //config.sdResumePos = 0; player.sendCommand({PR_PLAY, id}); commandFound=true; diff --git a/yoRadio/src/core/netserver.h b/yoRadio/src/core/netserver.h index be015d0..2584aa7 100644 --- a/yoRadio/src/core/netserver.h +++ b/yoRadio/src/core/netserver.h @@ -5,22 +5,28 @@ #include "../AsyncWebServer/ESPAsyncWebServer.h" #include "AsyncUDP.h" -enum requestType_e : uint8_t { PLAYLIST=1, STATION=2, STATIONNAME=3, ITEM=4, TITLE=5, VOLUME=6, NRSSI=7, BITRATE=8, MODE=9, EQUALIZER=10, BALANCE=11, PLAYLISTSAVED=12, GETMODE=13, GETINDEX=14, GETACTIVE=15, GETSYSTEM=16, GETSCREEN=17, GETTIMEZONE=18, GETWEATHER=19, GETCONTROLS=20, DSPON=21, SDPOS=22, SDLEN=23, SDSNUFFLE=24, SDINIT=25, GETPLAYERMODE=26, CHANGEMODE=27 }; +enum requestType_e : uint8_t { PLAYLIST=1, STATION=2, STATIONNAME=3, ITEM=4, TITLE=5, VOLUME=6, NRSSI=7, BITRATE=8, MODE=9, EQUALIZER=10, BALANCE=11, PLAYLISTSAVED=12, STARTUP=13, GETINDEX=14, GETACTIVE=15, GETSYSTEM=16, GETSCREEN=17, GETTIMEZONE=18, GETWEATHER=19, GETCONTROLS=20, DSPON=21, SDPOS=22, SDLEN=23, SDSNUFFLE=24, SDINIT=25, GETPLAYERMODE=26, CHANGEMODE=27 }; enum import_e : uint8_t { IMDONE=0, IMPL=1, IMWIFI=2 }; const char emptyfs_html[] PROGMEM = R"( -ёRadio - WEB Board Uploader + + +

ёRadio - WEB Board Uploader


Select ALL files from yoRadio/data/www/
and upload them using the form below

-
+


-= OPTIONAL =-
You can also upload playlist.csv
and wifi.csv files from your backup
@@ -28,9 +34,9 @@ input[type=text],input[type=password]{width:170px;background:#272727;color:#e3d2

-
+

-
+ -= OPTIONAL =-
If you can't connect from PC to 192.168.4.1 address
setup WiFi connection first
@@ -39,9 +45,38 @@ input[type=text],input[type=password]{width:170px;background:#272727;color:#e3d2
- +
powered by ёRadio
+ + + +)"; +const char index_html[] PROGMEM = R"( + + + + + + + + + + + + + + + + + +
+ + )"; - struct nsRequestParams_t { requestType_e type; diff --git a/yoRadio/src/core/options.h b/yoRadio/src/core/options.h index 4a909df..03d2376 100644 --- a/yoRadio/src/core/options.h +++ b/yoRadio/src/core/options.h @@ -1,7 +1,7 @@ #ifndef options_h #define options_h -#define YOVERSION "0.9.434" +#define YOVERSION "0.9.511" /******************************************************* DO NOT EDIT THIS FILE. diff --git a/yoRadio/src/core/player.cpp b/yoRadio/src/core/player.cpp index 2a52361..0436afc 100644 --- a/yoRadio/src/core/player.cpp +++ b/yoRadio/src/core/player.cpp @@ -186,6 +186,7 @@ void Player::setOutputPins(bool isPlaying) { void Player::_play(uint16_t stationId) { log_i("%s called, stationId=%d", __func__, stationId); setError(""); + setDefaults(); remoteStationName = false; config.setDspOn(1); config.vuThreshold = 0; @@ -193,21 +194,23 @@ void Player::_play(uint16_t stationId) { config.screensaverTicks=SCREENSAVERSTARTUPDELAY; config.screensaverPlayingTicks=SCREENSAVERSTARTUPDELAY; if(config.getMode()!=PM_SDCARD) { - display.putRequest(PSTOP); + display.putRequest(PSTOP); } setOutputPins(false); //config.setTitle(config.getMode()==PM_WEB?const_PlConnect:""); + if(!config.loadStation(stationId)) return; config.setTitle(config.getMode()==PM_WEB?const_PlConnect:"[next track]"); config.station.bitrate=0; config.setBitrateFormat(BF_UNCNOWN); - config.loadStation(stationId); + _loadVol(config.store.volume); display.putRequest(DBITRATE); display.putRequest(NEWSTATION); netserver.requestOnChange(STATION, 0); netserver.loop(); netserver.loop(); - config.setSmartStart(0); + if(config.store.smartstart!=2) + config.setSmartStart(0); bool isConnected = false; if(config.getMode()==PM_SDCARD && SDC_CS!=255){ isConnected=connecttoFS(sdman,config.station.url,config.sdResumePos==0?_resumeFilePos:config.sdResumePos-player.sd_min); @@ -223,7 +226,8 @@ void Player::_play(uint16_t stationId) { config.saveValue(&config.store.lastSdStation, stationId); } //config.setTitle(""); - config.setSmartStart(1); + if(config.store.smartstart!=2) + config.setSmartStart(1); netserver.requestOnChange(MODE, 0); setOutputPins(true); display.putRequest(NEWMODE, PLAYER); @@ -268,7 +272,7 @@ void Player::prev() { uint16_t lastStation = config.lastStation(); if(config.getMode()==PM_WEB || !config.store.sdsnuffle){ - if (lastStation == 1) config.lastStation(config.store.countStation); else config.lastStation(lastStation-1); + if (lastStation == 1) config.lastStation(config.playlistLength()); else config.lastStation(lastStation-1); } sendCommand({PR_PLAY, config.lastStation()}); } @@ -276,9 +280,9 @@ void Player::prev() { void Player::next() { uint16_t lastStation = config.lastStation(); if(config.getMode()==PM_WEB || !config.store.sdsnuffle){ - if (lastStation == config.store.countStation) config.lastStation(1); else config.lastStation(lastStation+1); + if (lastStation == config.playlistLength()) config.lastStation(1); else config.lastStation(lastStation+1); }else{ - config.lastStation(random(1, config.store.countStation)); + config.lastStation(random(1, config.playlistLength())); } sendCommand({PR_PLAY, config.lastStation()}); } diff --git a/yoRadio/src/core/telnet.cpp b/yoRadio/src/core/telnet.cpp index 8fe5baf..9ed812a 100644 --- a/yoRadio/src/core/telnet.cpp +++ b/yoRadio/src/core/telnet.cpp @@ -292,7 +292,8 @@ void Telnet::on_input(const char* str, uint8_t clientId) { int sb; if (sscanf(str, "play(%d)", &sb) == 1 || sscanf(str, "cli.play(\"%d\")", &sb) == 1 || sscanf(str, "play %d", &sb) == 1 ) { if (sb < 1) sb = 1; - if (sb >= config.store.countStation) sb = config.store.countStation; + uint16_t cs = config.playlistLength(); + if (sb >= cs) sb = cs; player.sendCommand({PR_PLAY, (uint16_t)sb}); return; } diff --git a/yoRadio/src/displays/nextion.cpp b/yoRadio/src/displays/nextion.cpp index 08bc409..9c8024c 100644 --- a/yoRadio/src/displays/nextion.cpp +++ b/yoRadio/src/displays/nextion.cpp @@ -209,14 +209,14 @@ void Nextion::loop() { if(strcmp(scanBuf, "up") == 0) { display.resetQueue(); int p = display.currentPlItem - 1; - if (p < 1) p = config.store.countStation; + if (p < 1) p = config.playlistLength(); display.currentPlItem = p; display.putRequest(DRAWPLAYLIST, p); } if(strcmp(scanBuf, "dn") == 0) { display.resetQueue(); int p = display.currentPlItem + 1; - if (p > config.store.countStation) p = 1; + if (p > config.playlistLength()) p = 1; display.currentPlItem = p; display.putRequest(DRAWPLAYLIST, p); }