From eaecd7c0e4b42f863ef4a887307aaf5c61387a00 Mon Sep 17 00:00:00 2001 From: Thomas Farstrike Date: Sat, 14 Jun 2025 11:54:38 +0200 Subject: [PATCH] OSUpdate: comments --- .../__init__.mpy | Bin 3687 -> 0 bytes .../aiohttp_ws.mpy | Bin 3634 -> 0 bytes draft_code/aiohttp_read_and_send.py | 69 -- draft_code/animations.py | 304 -------- draft_code/apps.py_dont_compile_mpy_dontwork | 449 ----------- draft_code/asyncwebsocketclient.py | 284 ------- draft_code/dropdown_switch.py | 9 - draft_code/files_to_scripts.py | 54 -- draft_code/image_decoder.py | 39 - draft_code/image_tests.py | 42 - draft_code/include_in_build.py | 2 - draft_code/keyboard.py | 46 -- draft_code/keyboard_test.py | 110 --- draft_code/keyboard_test_ai.py | 69 -- draft_code/keyboard_test_diy.py | 113 --- draft_code/keyboard_test_diy_again.py | 121 --- draft_code/keyboard_test_diy_closer.py | 114 --- draft_code/keyboard_test_diy_closer_works.py | 114 --- draft_code/keyboard_test_onscreen.py | 103 --- draft_code/keyboard_test_onscreen_again.py | 92 --- draft_code/keyboard_test_works_simplify.py | 103 --- draft_code/main.c_with_chroot | 81 -- draft_code/microdot_webserver.py | 114 --- ...micropython_async_websocket_client_test.py | 52 -- draft_code/modwebsocket_test.py | 116 --- .../modwebsocket_test_workaround_mask_key.py | 201 ----- draft_code/my_websocket_test.py | 49 -- draft_code/nostr_receive.py | 110 --- draft_code/nwc-demo.py | 214 ------ draft_code/qmi8658_reworked.py | 142 ---- draft_code/qrdecode.py | 39 - draft_code/queue_test.py | 64 -- draft_code/saved_functions.py | 727 ------------------ draft_code/saved_uasyncio_demo.py | 133 ---- draft_code/screen_capture.py | 80 -- draft_code/sdl2_demo.py | 79 -- draft_code/secp256k1_tests.py | 51 -- draft_code/simple_thread.py | 77 -- draft_code/test_aes_cbc.py | 25 - draft_code/test_aes_cbc_iv.py | 46 -- draft_code/timers.py | 11 - draft_code/video_player/README.md | 2 - draft_code/video_player/convert_video.sh | 3 - draft_code/video_player/player.py | 5 - draft_code/webcam_snippets.py | 77 -- draft_code/websocket_nostr_receive.py | 97 --- draft_code/websocket_nostr_test.py | 23 - draft_code/websocket_raw_nostr_test.py | 75 -- ..._nostr_test.py_worked_without_ping_payload | 57 -- ...py_worked_without_ping_payload_still_works | 68 -- .../assets/osupdate.py | 1 + 51 files changed, 1 insertion(+), 5055 deletions(-) delete mode 100644 draft_code/aiohttp_compiled_mip_installed_but_missing_bugfix_of_chunked_reading/__init__.mpy delete mode 100644 draft_code/aiohttp_compiled_mip_installed_but_missing_bugfix_of_chunked_reading/aiohttp_ws.mpy delete mode 100644 draft_code/aiohttp_read_and_send.py delete mode 100644 draft_code/animations.py delete mode 100644 draft_code/apps.py_dont_compile_mpy_dontwork delete mode 100644 draft_code/asyncwebsocketclient.py delete mode 100644 draft_code/dropdown_switch.py delete mode 100644 draft_code/files_to_scripts.py delete mode 100644 draft_code/image_decoder.py delete mode 100644 draft_code/image_tests.py delete mode 100644 draft_code/include_in_build.py delete mode 100644 draft_code/keyboard.py delete mode 100644 draft_code/keyboard_test.py delete mode 100644 draft_code/keyboard_test_ai.py delete mode 100644 draft_code/keyboard_test_diy.py delete mode 100644 draft_code/keyboard_test_diy_again.py delete mode 100644 draft_code/keyboard_test_diy_closer.py delete mode 100644 draft_code/keyboard_test_diy_closer_works.py delete mode 100644 draft_code/keyboard_test_onscreen.py delete mode 100644 draft_code/keyboard_test_onscreen_again.py delete mode 100644 draft_code/keyboard_test_works_simplify.py delete mode 100644 draft_code/main.c_with_chroot delete mode 100644 draft_code/microdot_webserver.py delete mode 100644 draft_code/micropython_async_websocket_client_test.py delete mode 100644 draft_code/modwebsocket_test.py delete mode 100644 draft_code/modwebsocket_test_workaround_mask_key.py delete mode 100644 draft_code/my_websocket_test.py delete mode 100644 draft_code/nostr_receive.py delete mode 100644 draft_code/nwc-demo.py delete mode 100644 draft_code/qmi8658_reworked.py delete mode 100644 draft_code/qrdecode.py delete mode 100644 draft_code/queue_test.py delete mode 100644 draft_code/saved_functions.py delete mode 100644 draft_code/saved_uasyncio_demo.py delete mode 100644 draft_code/screen_capture.py delete mode 100644 draft_code/sdl2_demo.py delete mode 100644 draft_code/secp256k1_tests.py delete mode 100644 draft_code/simple_thread.py delete mode 100644 draft_code/test_aes_cbc.py delete mode 100644 draft_code/test_aes_cbc_iv.py delete mode 100644 draft_code/timers.py delete mode 100644 draft_code/video_player/README.md delete mode 100755 draft_code/video_player/convert_video.sh delete mode 100644 draft_code/video_player/player.py delete mode 100644 draft_code/webcam_snippets.py delete mode 100644 draft_code/websocket_nostr_receive.py delete mode 100644 draft_code/websocket_nostr_test.py delete mode 100644 draft_code/websocket_raw_nostr_test.py delete mode 100644 draft_code/websocket_raw_nostr_test.py_worked_without_ping_payload delete mode 100644 draft_code/websocket_raw_nostr_test.py_worked_without_ping_payload_still_works diff --git a/draft_code/aiohttp_compiled_mip_installed_but_missing_bugfix_of_chunked_reading/__init__.mpy b/draft_code/aiohttp_compiled_mip_installed_but_missing_bugfix_of_chunked_reading/__init__.mpy deleted file mode 100644 index 524ce853e0ca068f46a76a459c723f1b5a7dc5bc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3687 zcmeZeV~}rT7E(*h%+Dw(DbSCP&&WIWsrjlK~yjZ zg$Mfjn~THt1BIcJpSWv8Z~3G2jTcas!E zU2tk~ab|uV1DAoGfu1o#lQXk2Uoyz`c_j>d@hPdv`6;Okd>N^UDXB%p42`;cDXD2W zi6yBFESdQXLM{-Fr#}OqQ)NkNv8O)+N0g7J6GLM)M|xFe0RxA7lxF|~2PiNYc%Y_n z<>V)(6f>Cf6qh8Hlom6HB!e6tUz}N$%FtNfq-@Vslv~(5W4~t0}OoeMPOGk@FXVZ>zJOJSHd6#Q4I56lf6_tD4yfXQj5UBA`o8$iBSeIC?mco zv7Di@Nxeys4P*tAJp+>(Lt`LUN@;FEF$0^sYX}2JfPZiZ11}fIBr66U5LIl&z+}ZB zmtT;Y7oUu95?gU`4g-fresKu{3ojQ#qc2Zt9yr8#63dG+OHvv5ptdq_q$HLkGVl~6 z7A58uGjJ4uw6GPFmN2jdgoZG16(p7_*fA(&B<7_QXC!8)!b5`x z8umgq>8W|C6$M3h3|!T;`xoN+^hoN9Gh37>k0~g zkl9?!tSsOp%*qZ+@~k`{0UbD3A>1*@&(qJ{N&zaQkei=Unv<#ka!qDYY6=4@AIw~z z)V%bP3bU1_oAH8?1R5u2v|dC^4@%Ewu>l zTq_1Pc5pUIO<`c;^vO?71jVuy1FKkQUU6wbL4Hw5YKlTZQGQ8&a(<4L0s|YrYO#X8 zYO#W9F)tSgGq4II78K-ULUihbBZ!p;=6rC8#43TTB0sq#wM4hLq$o8pmw`|*SZ0-R!*0$gHQAw~=W+$Kz7+#yDc0z87;Cd^_yAx2CBye3Ryydg%+ z0(>S+VtfMpV%dSoEX^hyLfjpKDJ_B-nJI!fVz~m`VtGakVnRlYVj}fgjKRiCVln~( zAO^FTyb+5Svk|M9QeZM$h7^}jenNxL#tjm}fyo^nx0sYf^8Fh`wbYeVUDXV=)Qp0) zHVBJ~h$%CeF&^5a%y`%3QGB5- z`_Zi;GG+|PF|kfbn*?NUy2KzUkn1;NMpohAB^WMLaNor%Qm9aw$%HY|i!pX%a-+v4 zM=qKCq6W1MA|e}vg+*jGnlZ)&W|%Q1Hz^!)GtiMAVd78_k#+LJtX*Y?@%gv_V1zqACKUN~Q_y znZuiv*={;J3#q3nvnPYag-SPW5LPi^0!ts+5H74DRJO&0@mUm1dni~Ly7mnsB3lq1 z_EhFTc(}2Ifrq!lH$?%Gba)~DHDVOgGGY?b4oqfllu+gq%GWG!@Kf2eK|*8W1_{l; zsy5Rd^5YCf?%0YM!G!AvdYU}H$~g}5OwFi?j>QGuYy;}wem z(|lsFfyw;M4hLEp#f0)JL@OJjRaEqK0yjwLY}_EBufrr@AYhmzU?gCiv_ZmTgRqH+ zY4D~7^CpJK%^M`l0+T&D9YDTM+K}9+0P;A8c78)Dl2@m&9J$!S7;m0mW#iB65g^)- zrKD`Atf`@)q@by(q^_x^q8VjmlR?3`aj4ocvT>I|2I0c<`iUkRAn=!hC>=UszV-QgbY&2tP3>8r@V>smG z;Iye;sY!QFc=RndHl-&0TTV__qIhDKIb!Rjaa@Fvfv0>8Gbr5;h)u zMvO*GyG$5O823wvdU1sd)!cV+2Ic;p8zgl0Co?w*+;ZScY-DO=YUmE$7#!>^a7Z9Y zBzco6!=_L(ru0ZBy};zAh)AxKMy7^79fl3@-m(Wbil_;=HJUNihl-?{F~E2Yq56_e ziph-$j$CPtObz|oAjNzKH-dZ(Ql~HCWRN_U<=Vwo#$pRtjMY{)EYi`?QC6{3iqLga zQ&Uq>b@5WuaVv39RZ-VcPF0XkRyNQIax+dHMvb560l1YB>r_$oD9pW7OE&&4U|sFRma zBZD%}u1_Y6sRC|$?z#l+frg6#)0uNZCHqVm&j~S!xbN8~;IY-Li775H!+`0$n!wJ$ zdoC^;gw0M0cy7OY*~M$Sh^c_*9y3s)cTQL4-MDw>c9&2AFA;kq#_b~BW(?rS6!7}w z z#STKe8#aiTZ`>fPzv+{J|7HQ^Edm}}1p>AShzivQZxA*K-riu^!eG|LWWto(XmF~* zflDmkrs3lT5kCRPjo`utCLWk?)9?i(?u05HlyB4U9V8x%Djt$=)9?!<9*Qa+mT%MW z7bG5zDjtzj8!3dMq?IMs~RgxCU27!Pk2i32GRh~FS=Vb%hwzauvbCv1?=5n|nJ!k7#IwZc=k diff --git a/draft_code/aiohttp_compiled_mip_installed_but_missing_bugfix_of_chunked_reading/aiohttp_ws.mpy b/draft_code/aiohttp_compiled_mip_installed_but_missing_bugfix_of_chunked_reading/aiohttp_ws.mpy deleted file mode 100644 index 37f3b61d59e22f410e075715c19caddfa171f8ff..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3634 zcmeZeV~}rT=hI5e%+Dw(DbR<~@#V#O1(gi^e2K-CdC8gi3_L}Nc`5n13>;a-`FRWi zNttu3}VUoIXS7xC7Jno#SDDO`MCv| zIjIb6p+TMu3gM|q!THJAsU^Ot#l?x~sSHBl!M?@mA(aKG403Qu=bX&cyb=aI2n`nw zN-ZwP&nr%4Fo+Ki4oWR7O)V~Q&d)1JttjzL%u7s9En?s@&@<38W)LVX$|*=JDo$nK z%1tau&S2n5FUl`1U|=gRE@ogUFJ@@eRBp26NJ%V7WZ)@CEK1BRX5dNA$uCY#Vc;oB zO-xBGV&Ew+$}CAO0{I{>FEzP@!Cs)CD8D2>IX{O%C?hd1r8pxoJC#8#9&Ay3T2W$d zYJ3J%Z)sjZVsbVEo1&8wgF$>jQGRl2adCWkYEm)S_Yl<#93id|Aq-8*Ree(nr<@u_*q`6;OwdU+t?3>;vKI24_nJQzS^AOnk{Cxcje zY6&RXk}^w*88|@E%fJO9ix~tm@{3DAvBkhqkY7{+(qEFnz$=nulo+3sSe$BR!oXEs zYgJv#z~PZ!T*AN?T996pn3BpM;+zi-hs^vu1|hgl7+4IA8APgUt@QOFx_JDHGSf5j z7}(rhLm1eKi*p$GAc0cMAdy)dj|e!vvecqtkYNHIAt3?!hI)n!jrC3Hd_}3rshMS| z3}W%1h=7JvlW3DCS4vT0W*$Q$e`7U^q6Y(uVjzQ1e0(A(lH%jR%)Hc!lK6NAf#TG> zl=$M3A_fsKE2*+1wU|K&%m$}nu9VW;f?@_Ss8wL4QZNogwFHa{(U6m$m{QEZRg_wo zoDWJV;PfdHAD@_-SCU!;wLY~X6J$Lf*x{fQln72z3|z%Isi_4FLN@8Cd8rizMRp8a z@nBW+(t%`+|=CsqRO(&)N%$9s5SA)`3&5wh8pF? z#Wm%{npXPy8qtorQHi=$2D+BIF?zAuni}?2F;*JU2D+B9+M1g78v1(Ln)VD_EUX;x z?8C|dPlT*2;8e)UQjl1Z!N4jKoSc!Go2pPzs1|85uqtC$07^5unZ+3}RY8z6 zoT88mDdrSFc|)-X?5Vu`5|Dumtg3`mflMuC=+qG~U`%jO0|OtetQOJCgv^A_g`N7H zybXcUOkzw8fzr%k%ngCkEMjR5fzqsEtPO$EY+`H;fzs?^>{Ax10$ z{3c9d{2@lH0sgww5YN~2#s%}0)=_0}#%oq=D zbh+NJQADKCjPcM$5s@Y{#={#$M4HVQk8BhXX)$9wx=BFvri=HMzDq*72@8sStxsp3FB51mgKlm{N(XF^kO|x%Ase_sLM|}5+2X(vMhW?%OqY@dM>RDKWhEh@ zjV6o-H#$2DDWq-`Rs;o{>n3NXphFu(ls0bKY{ncHm=PJ6+*}YPqFh?m;FYVDqU9#U zE}|l!y3vfufa%a-q4G^ijSTNi7>{h~e}7b{d^3c1Y_n2B{rlrvwr<<5#gg2rp{<}+ zR9w*zuCAr7Ef)+oE!+^_V`qr>y{Q*G^DA!sii1rrFf~U_-d&6sj1~9 z8>$*|LacDxB%)`=a7d_XlL_PDpztF{x45_}H8MCkHXPfw@xigJFy8UaN)2__T>`gn zesElfT|{3%b=!6`<`Yhpo0VD`7_Pg7Y*%WigGw1}+rHV1<%Co0W@Q$LOg&V_5Gvy= zl$8oL#Yl)*#CU-jqZyMr=MGiQrzeD}cPcP23e{{fVT?0jG+{inW7DT(#wLMV4t%MN zY>jLUZNVFZgS`bnp}Sd?VN=VG(0A#PPI`gK{VFp;jFgHpU1}S;l=V%m4Aj)L)dK4i z613I*m9%vjj)0@^j*E+ciIbCn=}~1?5%H}Xh0Qh!n{O1haAgv(G-Ej?#42JXRBgl{ zR5tlOjGAOUv)50eh2xWEhprVSFZ8zkg52+N9inlZ!$ zW}Mg&Sf|GndSZu&mokSLqqCck!VVM0RHq;;N}RPpnJ?j>16OJzTSIT~hTvdto`awe z?J#3Zk90B$Om1a3=pf-;)UaGZM_XB2UBzRAh!5Bv1EzzAHi)Qg+yqLfhmUM_@!lZf zyJfQ($W@V$H0Bw!K|*HZ7A>aaEiSHL+KDkRxjEyoqmXZrRB^**K2 z3RRjgxwvi+R(EpVAgsC3jOp+OVL1`M&1Q^|AcjBK(#XK%CV_JiGiI?9IZpfCt*GGmMj%s41i zwb6vJ>5hxf24Ss3%AAKcZPsE+-XNm9(Tvf6<;bC<$F?ao)ZKK60Ov<==s|UwF&Qu( zbBf=l)KCwT4h9?C0X7&S?XcCw7cAHU7F35=y$#GcywxR8sCqj%nQn%r5{UK4>GV9V zblRfBpv2#CB_*YWJtf5<#UUjnAteD^;PFFBR3k>Q5F;kBP$Oos03#N$Fe6s6a3eOc z2qSi}C?gKBXd_Osn80MN0x2GeqDF>>s~a~+hy^A)aB_qcHQd;c+-$MXfiJYE;dX$z ziV)8RVKEVJaNswZG9KJ0EamLIQCM<=u$ZvcO=ouyE#u-M)X12+F}YD;q60@jQNtsU zo&c~OP=r;ia^MRql4^LWsRxZ`XFs7vCS@)m$&DtAKTH@?LF#=sg2M(>99nF0;0rI3 zYItP`)=(|f$Sl;zqQz{&1kuQiLt|sWCI_yFBB_S=8$`l{(nKORnlZu+jo9eG7gf~o z$w1o((^FvosNZo30=bI^luso$3QL(WnJ}hq6qZVE25F8iYWRU$vnEtCFNWqukA)6g zF+~mkG&hJufdl2BP?|{WMl;6b#u5e|ff>vx3Mt^|6M#owf)SHgVqh|Jqk^)4L{WSr z>jV~+O&cWQHg1rJ4@@qY=)jRsG=XD-a9mtq1}H}yXmH?4ESkWryFoZ!I7uWKY)zyP LlSoPfH~^9X!B0(2 diff --git a/draft_code/aiohttp_read_and_send.py b/draft_code/aiohttp_read_and_send.py deleted file mode 100644 index cd5ddd45..00000000 --- a/draft_code/aiohttp_read_and_send.py +++ /dev/null @@ -1,69 +0,0 @@ -import uasyncio as asyncio -import sys -from contextlib import suppress -import aiohttp -import _thread - -# Shared buffer for input lines -input_buffer = [] -lock = _thread.allocate_lock() # Thread-safe access to buffer - -# Thread function to read input and add to buffer -def read_input_thread(): - while True: - line = input() - with lock: - input_buffer.append(line) - if line == "exit": - break - -async def start_client(url: str) -> None: - name = input("Please enter your name: ") - - # Start the input reading thread - _thread.start_new_thread(read_input_thread, ()) - - async def dispatch(ws: aiohttp.ClientWebSocketResponse) -> None: - while True: - #msg = await ws.receive() - msg = await ws.__anext__() - - if msg.type is aiohttp.WSMsgType.TEXT: - print("Text: ", msg.data.strip()) - elif msg.type is aiohttp.WSMsgType.BINARY: - print("Binary: ", msg.data) - elif msg.type is aiohttp.WSMsgType.PING: - await ws.pong() - elif msg.type is aiohttp.WSMsgType.PONG: - print("Pong received") - else: - if msg.type is aiohttp.WSMsgType.CLOSE: - await ws.close() - elif msg.type is aiohttp.WSMsgType.ERROR: - print("Error during receive %s" % ws.exception()) - elif msg.type is aiohttp.WSMsgType.CLOSED: - pass - break - - async with aiohttp.ClientSession() as session: - async with session.ws_connect(url) as ws: - dispatch_task = asyncio.create_task(dispatch(ws)) - - # Poll the input buffer instead of to_thread - while True: - line = None - with lock: - if input_buffer: # Check if there's input - line = input_buffer.pop(0) # Get the first line - if line: - await ws.send_str(name + ": " + line) - if line == "exit": # Stop on "exit" - break - await asyncio.sleep_ms(100) # Avoid busy-waiting - - dispatch_task.cancel() - with suppress(asyncio.CancelledError): - await dispatch_task - -# Run the client -asyncio.run(start_client("wss://echo.websocket.events")) diff --git a/draft_code/animations.py b/draft_code/animations.py deleted file mode 100644 index bc1864be..00000000 --- a/draft_code/animations.py +++ /dev/null @@ -1,304 +0,0 @@ - -# Initialize - -import display_driver -import lvgl as lv - -import lvgl - -label = lvgl.label( lvgl.screen_active() ) -label.set_text( 'hi' ) - -animation = lvgl.anim_t() -animation.init() -animation.set_var( label ) -animation.set_values( 0, 100 ) -animation.set_time( 1000 ) - -animation.set_custom_exec_cb( lambda not_used, value : label.set_x( value )) - -#wait half a second before starting animation -animation.set_delay( 500 ) - -#play animation backward for 1 second after first play -animation.set_playback_time( 1000 ) -#repeat animation infinitely -animation.set_repeat_count( 10 ) -#animation.set_repeat_count( lvgl.ANIM_REPEAT.INFINITE ) -animation.set_repeat_delay( 500 ) - -animation.start() - - - -****************************** - - - -# Initialize - -import display_driver -import lvgl as lv - -import lvgl - -#create the slow short label -label1 = lvgl.label( lvgl.screen_active() ) -label1.set_text( 'hello 1' ) -label1.align( lvgl.ALIGN.CENTER, 0, -50 ) - -anim1 = lvgl.anim_t() -anim1.init() -anim1.set_var( label1 ) -#anim1.set_time( lvgl.anim_speed_to_time( 20, 0, 100 )) -anim1.set_time( 2000 ) -anim1.set_values( 0, 100 ) -anim1.set_repeat_count( 10 ) -anim1.set_repeat_delay( 2000 ) -anim1.set_custom_exec_cb( lambda not_used, value : label1.set_x( value )) - - -#create the fast long label -label2 = lvgl.label( lvgl.screen_active() ) -label2.set_text('hello 2') -label2.align(lvgl.ALIGN.CENTER,-100,0) - -anim2 = lvgl.anim_t() -anim2.init() -anim2.set_var( label2 ) -#anim2.set_time( lvgl.anim_speed_to_time( 40, -100, 100 )) -anim2.set_time( 40 * 200 ) -anim2.set_values( -100, 100 ) -anim2.set_custom_exec_cb( lambda not_used, value : label2.set_x( value )) -anim2.set_repeat_count( 10) -anim2.set_repeat_delay( 2000 ) - - -#Create the fast short label -label3 = lvgl.label( lvgl.screen_active() ) -label3.set_text( 'hello 3' ) -label3.align( lvgl.ALIGN.CENTER, -100, 50 ) - - -anim3 = lvgl.anim_t() -anim3.init() -anim3.set_var( label3 ) -#anim3.set_time( lvgl.anim_speed_to_time( 40, -100, 0 )) -anim3.set_time( 40 * 100) -anim3.set_values( -100, 0) -anim3.set_custom_exec_cb( lambda not_used, value : label3.set_x( value )) -anim3.set_repeat_count( 10 ) -anim3.set_repeat_delay( 40 * 100 + 2000 ) -#anim3.set_repeat_delay( lvgl.anim_speed_to_time( 40, -100, 0) + 2000 ) -#lvgl.anim_speed_to_time( 1, 2, 3) -#anim3.set_repeat_delay( 5000) -#lvgl.anim - -anim1.start() -anim2.start() -anim3.start() - - - - - - - - - -****************** - - - - -# Initialize - -import display_driver -import lvgl as lv - -import lvgl - -import lvgl - -#normal animation -label1 = lvgl.label( lvgl.screen_active() ) -label1.set_text( 'hello 1' ) -label1.align( lvgl.ALIGN.CENTER, -70, -60 ) - -anim1 = lvgl.anim_t() -anim1.init() -anim1.set_var( label1 ) -anim1.set_time( 1000 ) -anim1.set_values( -70, 20 ) -anim1.set_repeat_count( 100 ) -anim1.set_repeat_delay( 2000 ) -anim1.set_custom_exec_cb( lambda not_used, value : label1.set_x( value )) - - -#this animation bounces the label when it ends -label2 = lvgl.label( lvgl.screen_active() ) -label2.set_text( 'hello 2' ) -label2.align( lvgl.ALIGN.CENTER, 30, -60 ) - -anim2 = lvgl.anim_t() -anim2.init() -anim2.set_var( label2 ) -anim2.set_time( 1000 ) -anim2.set_values( 30, 120 ) -anim2.set_custom_exec_cb( lambda not_used, value : label2.set_x( value )) -anim2.set_repeat_count( 100) -anim2.set_repeat_delay( 2000 ) -anim2.set_path_cb( lvgl.anim_t.path_bounce ) - - -#this animation goes past the end point then comes back -label3 = lvgl.label( lvgl.screen_active() ) -label3.set_text( 'hello 3' ) -label3.align( lvgl.ALIGN.CENTER, -70, 60 ) - -anim3 = lvgl.anim_t() -anim3.init() -anim3.set_var( label3 ) -anim3.set_time( 1000 ) -anim3.set_values( -70, 20 ) -anim3.set_custom_exec_cb( lambda not_used, value : label3.set_x( value )) -anim3.set_repeat_count( 100 ) -anim3.set_repeat_delay( 2000 ) -anim3.set_path_cb( lvgl.anim_t.path_overshoot ) - - -#this animation slowly starts and then slowly ends -label4 = lvgl.label( lvgl.screen_active() ) -label4.set_text( 'hello 4' ) -label4.align( lvgl.ALIGN.CENTER, 30, 60 ) - -anim4 = lvgl.anim_t() -anim4.init() -anim4.set_var( label4 ) -anim4.set_time( 1000 ) -anim4.set_values( 30, 120 ) -anim4.set_custom_exec_cb( lambda not_used, value : label4.set_x( value )) -anim4.set_repeat_count( 100 ) -anim4.set_repeat_delay( 2000 ) -anim4.set_path_cb( lvgl.anim_t.path_ease_in_out ) - - -anim1.start() -anim2.start() -anim3.start() -anim4.start() - - - -******************** - - - - -# Initialize - -import display_driver -import lvgl as lv - - - -button = lv.button( lv.screen_active() ) -button.set_size( 50, 20 ) -button.center() - -anim1 = lv.anim_t() -anim1.init() -anim1.set_var( button ) -anim1.set_time( 1000 ) -anim1.set_values( -100, 100 ) -anim1.set_custom_exec_cb( lambda not_used, value : button.set_x( value )) - -anim2 = lv.anim_t() -anim2.init() -anim2.set_var( button ) -anim2.set_time( 150 ) -anim2.set_values( 100, 30 ) -anim2.set_custom_exec_cb( lambda not_used, value : button.set_x( value )) - -anim3 = lv.anim_t() -anim3.init() -anim3.set_var( button ) -anim3.set_time( 2000 ) -anim3.set_values( 30, -100 ) -anim3.set_custom_exec_cb( lambda not_used, value : button.set_x( value )) - -timeline = lv.anim_timeline_create() - - -# this works: -lv.anim_timeline_t.add(timeline,0,anim1) -lv.anim_timeline_t.add(timeline,2000,anim2) -lv.anim_timeline_t.add(timeline,3150,anim3) - -lv.anim_timeline_t.start(timeline) - -# to restart it: -#lv.anim_timeline_t.set_progress(timeline, 0) -#lv.anim_timeline_t.start(timeline) - -# or to reverse it: -#lv.anim_timeline_t.set_reverse(timeline,True) -#lv.anim_timeline_t.start(timeline) -#lv.anim_timeline_t.set_reverse(timeline,False) -#lv.anim_timeline_t.start(timeline) -# progress max is 65535, not 32k -#lv.anim_timeline_t.set_progress(timeline,65535) -#lv.anim_timeline_t.start(timeline) - - - -***************** clicking the button starts the animation: - - - - -# Initialize - -import display_driver -import lvgl as lv - - -label = lv.label( lv.screen_active() ) -label.set_text( 'hi' ) - -animation = lv.anim_t() -animation.init() -animation.set_var( label ) -animation.set_values( 0, 100 ) -animation.set_time( 1000 ) - -animation.set_custom_exec_cb( lambda not_used, value : label.set_x( value )) - -#wait half a second before starting animation -#animation.set_delay( 500 ) - -#play animation backward for 1 second after first play -#animation.set_playback_time( 1000 ) -#repeat animation infinitely -#animation.set_repeat_count( 10 ) -#animation.set_repeat_count( lvgl.ANIM_REPEAT.INFINITE ) -#animation.set_repeat_delay( 500 ) - -button = lv.button(lv.screen_active()) -button.set_size(60,30) -button.center() -#button.set_pos(100,100) -wifi_label=lv.label(button) -wifi_label.set_text(lv.SYMBOL.WIFI+" WiFi") -wifi_label.center() -#wifi_label.set_style_text_color(COLOR_DRAWER_BUTTONTEXT,0) - -def wifi_event(e): - animation.start() - -button.add_event_cb(wifi_event,lv.EVENT.CLICKED,None) - - - - - diff --git a/draft_code/apps.py_dont_compile_mpy_dontwork b/draft_code/apps.py_dont_compile_mpy_dontwork deleted file mode 100644 index c9a55a05..00000000 --- a/draft_code/apps.py_dont_compile_mpy_dontwork +++ /dev/null @@ -1,449 +0,0 @@ -import lvgl as lv - -import uio -import ujson -import uos - -import _thread -import traceback - -import mpos.info -import mpos.ui - -def good_stack_size(): - stacksize = 24*1024 - import sys - if sys.platform == "esp32": - stacksize = 16*1024 - return stacksize - -# Run the script in the current thread: -def execute_script(script_source, is_file, cwd=None, classname=None): - thread_id = _thread.get_ident() - compile_name = 'script' if not is_file else script_source - print(f"Thread {thread_id}: executing script with cwd: {cwd}") - - script_globals = {'lv': lv, '__name__': "__main__"} - import sys - import uos - import utime - - path_before = sys.path - if cwd: - sys.path.append(cwd) - - try: - if is_file: - mpy_file = script_source.rsplit('.py', 1)[0] + '.mpy' if '.py' in script_source else script_source + '.mpy' - try: - uos.stat(mpy_file) - source_file = mpy_file - except OSError: - source_file = script_source - mode = 'rb' if source_file.endswith('.mpy') else 'r' - print(f"Thread {thread_id}: reading {'bytecode' if mode == 'rb' else 'script'} from {source_file}") - - start_time = utime.ticks_ms() - f = open(source_file, mode) - try: - script_source = f.read() - finally: - f.close() - read_time = utime.ticks_diff(utime.ticks_ms(), start_time) - print(f"Thread {thread_id}: file read took {read_time} ms") - - try: - start_time = utime.ticks_ms() - compiled_script = script_source if isinstance(script_source, bytes) else compile(script_source, compile_name, 'exec') - compile_time = utime.ticks_diff(utime.ticks_ms(), start_time) - if not isinstance(script_source, bytes): - print(f"Thread {thread_id}: compilation took {compile_time} ms") - - exec(compiled_script, script_globals) - if classname: - main_activity = script_globals.get(classname) - if main_activity: - Activity.startActivity(None, Intent(activity_class=main_activity)) - else: - print("Warning: could not find main_activity") - except Exception as e: - print(f"Thread {thread_id}: exception during execution:") - traceback.print_exception(type(e), e, getattr(e, '__traceback__', None)) - print(f"Thread {thread_id}: script {compile_name} finished") - except Exception as e: - print(f"Thread {thread_id}: error:") - traceback.print_exception(type(e), e, getattr(e, '__traceback__', None)) - sys.path = path_before - -# Run the script in a new thread: -# TODO: check if the script exists here instead of launching a new thread? -def execute_script_new_thread(scriptname, is_file): - print(f"main.py: execute_script_new_thread({scriptname},{is_file})") - try: - # 168KB maximum at startup but 136KB after loading display, drivers, LVGL gui etc so let's go for 128KB for now, still a lot... - # But then no additional threads can be created. A stacksize of 32KB allows for 4 threads, so 3 in the app itself, which might be tight. - # 16KB allows for 10 threads in the apps, but seems too tight for urequests on unix (desktop) targets - # 32KB seems better for the camera, but it forced me to lower other app threads from 16 to 12KB - #_thread.stack_size(24576) # causes camera issue... - # NOTE: This doesn't do anything if apps are started in the same thread! - if "camtest" in scriptname: - print("Starting camtest with extra stack size!") - stack=32*1024 - elif "appstore"in scriptname: - print("Starting appstore with extra stack size!") - stack=24*1024 # this doesn't do anything because it's all started in the same thread - else: - stack=16*1024 # 16KB doesn't seem to be enough for the AppStore app on desktop - stack = mpos.apps.good_stack_size() - print(f"app.py: setting stack size for script to {stack}") - _thread.stack_size(stack) - _thread.start_new_thread(execute_script, (scriptname, is_file)) - except Exception as e: - print("main.py: execute_script_new_thread(): error starting new thread thread: ", e) - -def start_app_by_name(app_name, is_launcher=False): - mpos.ui.set_foreground_app(app_name) - custom_app_dir=f"apps/{app_name}" - builtin_app_dir=f"builtin/apps/{app_name}" - try: - stat = uos.stat(custom_app_dir) - start_app(custom_app_dir, is_launcher) - except OSError: - start_app(builtin_app_dir, is_launcher) - -def start_app(app_dir, is_launcher=False): - print(f"main.py start_app({app_dir},{is_launcher})") - mpos.ui.set_foreground_app(app_dir) # would be better to store only the app name... - manifest_path = f"{app_dir}/META-INF/MANIFEST.JSON" - app = mpos.apps.parse_manifest(manifest_path) - print(f"start_app parsed manifest and got: {str(app)}") - main_launcher_activity = find_main_launcher_activity(app) - if not main_launcher_activity: - print(f"WARNING: can't start {app_dir} because no main_launcher_activity was found.") - return - start_script_fullpath = f"{app_dir}/{main_launcher_activity.get('entrypoint')}" - execute_script(start_script_fullpath, True, app_dir + "/assets/", main_launcher_activity.get("classname")) - # Launchers have the bar, other apps don't have it - if is_launcher: - mpos.ui.open_bar() - else: - mpos.ui.close_bar() - -def restart_launcher(): - mpos.ui.empty_screen_stack() - # No need to stop the other launcher first, because it exits after building the screen - start_app_by_name("com.micropythonos.launcher", True) # Would be better to query the PackageManager for Activities that are launchers - -def find_main_launcher_activity(app): - result = None - for activity in app.activities: - if not activity.get("entrypoint") or not activity.get("classname"): - print(f"Warning: activity {activity} has no entrypoint and classname, skipping...") - continue - print("checking activity's intent_filters...") - for intent_filter in activity.get("intent_filters"): - print("checking intent_filter...") - if intent_filter.get("action") == "main" and intent_filter.get("category") == "launcher": - print("found main_launcher!") - result = activity - break - return result - -def is_launcher(app_name): - print(f"checking is_launcher for {app_name}") - # Simple check, could be more elaborate by checking the MANIFEST.JSON for the app... - return "launcher" in app_name - - -class App: - def __init__(self, name, publisher, short_description, long_description, icon_url, download_url, fullname, version, category, activities): - self.name = name - self.publisher = publisher - self.short_description = short_description - self.long_description = long_description - self.icon_url = icon_url - self.download_url = download_url - self.fullname = fullname - self.version = version - self.category = category - self.image = None - self.image_dsc = None - self.activities = activities - - def __str__(self): - return (f"App(name='{self.name}', " - f"publisher='{self.publisher}', " - f"short_description='{self.short_description}', " - f"version='{self.version}', " - f"category='{self.category}', " - f"activities={self.activities})") - -def parse_manifest(manifest_path): - # Default values for App object - default_app = App( - name="Unknown", - publisher="Unknown", - short_description="", - long_description="", - icon_url="", - download_url="", - fullname="Unknown", - version="0.0.0", - category="", - activities=[] - ) - try: - with open(manifest_path, 'r') as f: - app_info = ujson.load(f) - #print(f"parsed app: {app_info}") - # Create App object with values from manifest, falling back to defaults - return App( - name=app_info.get("name", default_app.name), - publisher=app_info.get("publisher", default_app.publisher), - short_description=app_info.get("short_description", default_app.short_description), - long_description=app_info.get("long_description", default_app.long_description), - icon_url=app_info.get("icon_url", default_app.icon_url), - download_url=app_info.get("download_url", default_app.download_url), - fullname=app_info.get("fullname", default_app.fullname), - version=app_info.get("version", default_app.version), - category=app_info.get("category", default_app.category), - activities=app_info.get("activities", default_app.activities) - ) - except OSError: - print(f"parse_manifest: error loading manifest_path: {manifest_path}") - return default_app - - - -def auto_connect(): - builtin_auto_connect = "builtin/system/WifiService.py" - try: - print(f"Starting {builtin_auto_connect}...") - stat = uos.stat(builtin_auto_connect) - execute_script_new_thread(builtin_auto_connect, True) - except Exception as e: - print("Couldn't execute {builtin_auto_connect} because exception {e}, continuing...") - - -class Activity: - - def __init__(self): - self.intent = None # Store the intent that launched this activity - self.result = None - self._result_callback = None - - def onCreate(self): - pass - def onStart(self, screen): - pass - def onResume(self, screen): - pass - def onPause(self, screen): - pass - def onStop(self, screen): - pass - def onDestroy(self, screen): - pass - - def setContentView(self, screen): - mpos.ui.setContentView(self, screen) - - def startActivity(self, intent): - ActivityNavigator.startActivity(intent) - - def startActivityForResult(self, intent, result_callback): - ActivityNavigator.startActivityForResult(intent, result_callback) - - def initError(self, e): - print(f"WARNING: You might have inherited from Activity with a custom __init__() without calling super().__init__(). Got AttributeError: {e}") - - def getIntent(self): - try: - return self.intent - except AttributeError as e: - self.initError(e) - - def setResult(self, result_code, data=None): - """Set the result to be returned when the activity finishes.""" - try: - self.result = {"result_code": result_code, "data": data or {}} - except AttributeError as e: - self.initError(e) - - def finish(self): - mpos.ui.back_screen() - try: - if self._result_callback and self.result: - self._result_callback(self.result) - self._result_callback = None # Clean up - except AttributeError as e: - self.initError(e) - -class Intent: - def __init__(self, activity_class=None, action=None, data=None, extras=None): - self.activity_class = activity_class # Explicit target (e.g., SettingsActivity) - self.action = action # Action string (e.g., "view", "share") - self.data = data # Single data item (e.g., URL) - self.extras = extras or {} # Dictionary for additional data - self.flags = {} # Simplified flags: {"clear_top": bool, "no_history": bool, "no_animation": bool} - - def addFlag(self, flag, value=True): - self.flags[flag] = value - return self - - def putExtra(self, key, value): - self.extras[key] = value - return self - - -class ActivityNavigator: - @staticmethod - def startActivity(intent): - if not isinstance(intent, Intent): - raise ValueError("Must provide an Intent") - if intent.action: # Implicit intent: resolve handlers - handlers = APP_REGISTRY.get(intent.action, []) - if len(handlers) == 1: - intent.activity_class = handlers[0] - ActivityNavigator._launch_activity(intent) - elif handlers: - ActivityNavigator._show_chooser(intent, handlers) - else: - raise ValueError(f"No handlers for action: {intent.action}") - else: - ActivityNavigator._launch_activity(intent) - - @staticmethod - def startActivityForResult(intent, result_callback): - """Launch an activity and pass a callback for the result.""" - if not isinstance(intent, Intent): - raise ValueError("Must provide an Intent") - if intent.action: # Implicit intent: resolve handlers - handlers = APP_REGISTRY.get(intent.action, []) - if len(handlers) == 1: - intent.activity_class = handlers[0] - return ActivityNavigator._launch_activity(intent, result_callback) - elif handlers: - ActivityNavigator._show_chooser(intent, handlers) - return None # Chooser handles result forwarding - else: - raise ValueError(f"No handlers for action: {intent.action}") - else: - return ActivityNavigator._launch_activity(intent, result_callback) - - @staticmethod - def _launch_activity(intent, result_callback=None): - """Launch an activity and set up result callback.""" - activity = intent.activity_class() - activity.intent = intent - activity._result_callback = result_callback # Pass callback to activity - activity.onCreate() - return activity - - @staticmethod - def _show_chooser(intent, handlers): - chooser_intent = Intent(ChooserActivity, extras={"original_intent": intent, "handlers": [h.__name__ for h in handlers]}) - ActivityNavigator._launch_activity(chooser_intent) - - -class ChooserActivity(Activity): - def __init__(self): - super().__init__() - - def onCreate(self): - screen = lv.obj() - # Get handlers from intent extras - original_intent = self.getIntent().extras.get("original_intent") - handlers = self.getIntent().extras.get("handlers", []) - label = lv.label(screen) - label.set_text("Choose an app") - label.set_pos(10, 10) - - for i, handler_name in enumerate(handlers): - btn = lv.btn(screen) - btn.set_user_data(f"handler_{i}") - btn_label = lv.label(btn) - btn_label.set_text(handler_name) - btn.set_pos(10, 50 * (i + 1) + 10) - btn.add_event_cb(lambda e, h=handler_name, oi=original_intent: self._select_handler(h, oi), lv.EVENT.CLICKED) - self.setContentView(screen) - - def _select_handler(self, handler_name, original_intent): - for handler in APP_REGISTRY.get(original_intent.action, []): - if handler.__name__ == handler_name: - original_intent.activity_class = handler - navigator.startActivity(original_intent) - break - navigator.finish() # Close chooser - - def onStop(self, screen): - if self.getIntent() and self.getIntent().getStringExtra("destination") == "ChooserActivity": - print("Stopped for Chooser") - else: - print("Stopped for other screen") - - -class ViewActivity(Activity): - def __init__(self): - super().__init__() - - def onCreate(self): - screen = lv.obj() - # Get content from intent (prefer extras.url, fallback to data) - content = self.getIntent().extras.get("url", self.getIntent().data or "No content") - label = lv.label(screen) - label.set_user_data("content_label") - label.set_text(f"Viewing: {content}") - label.center() - self.setContentView(screen) - - def onStart(self, screen): - content = self.getIntent().extras.get("url", self.getIntent().data or "No content") - for i in range(screen.get_child_cnt()): - if screen.get_child(i).get_user_data() == "content_label": - screen.get_child(i).set_text(f"Viewing: {content}") - - def onStop(self, screen): - if self.getIntent() and self.getIntent().getStringExtra("destination") == "ViewActivity": - print("Stopped for View") - else: - print("Stopped for other screen") - -class ShareActivity(Activity): - def __init__(self): - super().__init__() - - def onCreate(self): - screen = lv.obj() - # Get text from intent (prefer extras.text, fallback to data) - text = self.getIntent().extras.get("text", self.getIntent().data or "No text") - label = lv.label(screen) - label.set_user_data("share_label") - label.set_text(f"Share: {text}") - label.set_pos(10, 10) - - btn = lv.btn(screen) - btn.set_user_data("share_btn") - btn_label = lv.label(btn) - btn_label.set_text("Share") - btn.set_pos(10, 50) - btn.add_event_cb(lambda e: self._share_content(text), lv.EVENT.CLICKED) - self.setContentView(screen) - - def _share_content(self, text): - # Dispatch to another app (e.g., MessagingActivity) or simulate sharing - print(f"Sharing: {text}") # Placeholder for actual sharing - # Example: Launch another share handler - navigator.startActivity(Intent(action="share", data=text)) - navigator.finish() # Close ShareActivity - - def onStop(self, screen): - if self.getIntent() and self.getIntent().getStringExtra("destination") == "ShareActivity": - print("Stopped for Share") - else: - print("Stopped for other screen") - -APP_REGISTRY = { # This should be handled by a new class PackageManager: - "view": [ViewActivity], # Hypothetical activities - "share": [ShareActivity] -} diff --git a/draft_code/asyncwebsocketclient.py b/draft_code/asyncwebsocketclient.py deleted file mode 100644 index 01967d5c..00000000 --- a/draft_code/asyncwebsocketclient.py +++ /dev/null @@ -1,284 +0,0 @@ -import socket -import asyncio as a -import binascii as b -import random as r -from collections import namedtuple -import re -import struct -import ssl - -# Opcodes -OP_CONT = const(0x0) -OP_TEXT = const(0x1) -OP_BYTES = const(0x2) -OP_CLOSE = const(0x8) -OP_PING = const(0x9) -OP_PONG = const(0xa) - -# Close codes -CLOSE_OK = const(1000) -CLOSE_GOING_AWAY = const(1001) -CLOSE_PROTOCOL_ERROR = const(1002) -CLOSE_DATA_NOT_SUPPORTED = const(1003) -CLOSE_BAD_DATA = const(1007) -CLOSE_POLICY_VIOLATION = const(1008) -CLOSE_TOO_BIG = const(1009) -CLOSE_MISSING_EXTN = const(1010) -CLOSE_BAD_CONDITION = const(1011) - -URL_RE = re.compile(r'(wss|ws)://([A-Za-z0-9-\.]+)(?:\:([0-9]+))?(/.+)?') -URI = namedtuple('URI', ('protocol', 'hostname', 'port', 'path')) - -class AsyncWebsocketClient: - def __init__(self, ms_delay_for_read: int = 5): - self._open = False - self.delay_read = ms_delay_for_read - self._lock_for_open = a.Lock() - self.sock = None - - async def open(self, new_val: bool = None): - await self._lock_for_open.acquire() - if new_val is not None: - if not new_val and self.sock: - self.sock.close() - self.sock = None - self._open = new_val - to_return = self._open - self._lock_for_open.release() - return to_return - - async def close(self): - return await self.open(False) - - def urlparse(self, uri): - """Parse ws or wss:// URLs""" - match = URL_RE.match(uri) - if match: - protocol, host, port, path = match.group(1), match.group(2), match.group(3), match.group(4) - - if protocol not in ['ws', 'wss']: - raise ValueError('Scheme {} is invalid'.format(protocol)) - - if port is None: - port = (80, 443)[protocol == 'wss'] - - return URI(protocol, host, int(port), path) - - async def a_readline(self): - line = None - while line is None: - line = self.sock.readline() - await a.sleep_ms(self.delay_read) - - return line - - async def a_read(self, size: int = None): - if size == 0: - return b'' - chunks = [] - - while True: - b = self.sock.read(size) - await a.sleep_ms(self.delay_read) - - # Continue reading if the socket returns None - if b is None: continue - - # In some cases, the socket will return an empty bytes - # after PING or PONG frames, we need to ignore them. - if len(b) == 0: break - - chunks.append(b) - size -= len(b) - - # After reading the first chunk, we can break if size is None or 0 - if size is None or size == 0: break - - # Join all the chunks and return them - return b''.join(chunks) - - async def handshake(self, uri, headers=[], keyfile=None, certfile=None, cafile=None, cert_reqs=0): - if self.sock: - self.close() - - self.sock = socket.socket() - self.uri = self.urlparse(uri) - ai = socket.getaddrinfo(self.uri.hostname, self.uri.port) - addr = ai[0][4] - - self.sock.connect(addr) - self.sock.setblocking(False) - - if self.uri.protocol == 'wss': - cadata = None - if not cafile is None: - with open(cafile, 'rb') as f: - cadata = f.read() - self.sock = ssl.wrap_socket( - self.sock, server_side=False, - key=keyfile, cert=certfile, - cert_reqs=cert_reqs, # 0 - NONE, 1 - OPTIONAL, 2 - REQUIED - cadata=cadata, - server_hostname=self.uri.hostname - ) - - def send_header(header, *args): - self.sock.write(header % args + '\r\n') - - # Sec-WebSocket-Key is 16 bytes of random base64 encoded - key = b.b2a_base64(bytes(r.getrandbits(8) - for _ in range(16)))[:-1] - - send_header(b'GET %s HTTP/1.1', self.uri.path or '/') - send_header(b'Host: %s:%s', self.uri.hostname, self.uri.port) - send_header(b'Connection: Upgrade') - send_header(b'Upgrade: websocket') - send_header(b'Sec-WebSocket-Key: %s', key) - send_header(b'Sec-WebSocket-Version: 13') - send_header(b'Origin: http://{hostname}:{port}'.format( - hostname=self.uri.hostname, - port=self.uri.port) - ) - - for key, value in headers: - send_header(b'%s: %s', key, value) - - send_header(b'') - - line = await self.a_readline() - header = (line)[:-2] - if not header.startswith(b'HTTP/1.1 101 '): - raise Exception(header) - - # We don't (currently) need these headers - # FIXME: should we check the return key? - while header: - line = await self.a_readline() - header = (line)[:-2] - - return await self.open(True) - - async def read_frame(self, max_size=None): - # Frame header - byte1, byte2 = struct.unpack('!BB', await self.a_read(2)) - - # Byte 1: FIN(1) _(1) _(1) _(1) OPCODE(4) - fin = bool(byte1 & 0x80) - opcode = byte1 & 0x0f - - # Byte 2: MASK(1) LENGTH(7) - mask = bool(byte2 & (1 << 7)) - length = byte2 & 0x7f - - if length == 126: # Magic number, length header is 2 bytes - length, = struct.unpack('!H', await self.a_read(2)) - elif length == 127: # Magic number, length header is 8 bytes - length, = struct.unpack('!Q', await self.a_read(8)) - - if mask: # Mask is 4 bytes - mask_bits = await self.a_read(4) - - try: - data = await self.a_read(length) - except MemoryError: - # We can't receive this many bytes, close the socket - self.close(code=CLOSE_TOO_BIG) - # await self._stream.drain() - return True, OP_CLOSE, None - - if mask: - data = bytes(b ^ mask_bits[i % 4] - for i, b in enumerate(data)) - - return fin, opcode, data - - def write_frame(self, opcode, data=b''): - fin = True - mask = True # messages sent by client are masked - - length = len(data) - - # Frame header - # Byte 1: FIN(1) _(1) _(1) _(1) OPCODE(4) - byte1 = 0x80 if fin else 0 - byte1 |= opcode - - # Byte 2: MASK(1) LENGTH(7) - byte2 = 0x80 if mask else 0 - - if length < 126: # 126 is magic value to use 2-byte length header - byte2 |= length - self.sock.write(struct.pack('!BB', byte1, byte2)) - - elif length < (1 << 16): # Length fits in 2-bytes - byte2 |= 126 # Magic code - self.sock.write(struct.pack('!BBH', byte1, byte2, length)) - - elif length < (1 << 64): - byte2 |= 127 # Magic code - self.sock.write(struct.pack('!BBQ', byte1, byte2, length)) - - else: - raise ValueError() - - if mask: # Mask is 4 bytes - mask_bits = struct.pack('!I', r.getrandbits(32)) - self.sock.write(mask_bits) - data = bytes(b ^ mask_bits[i % 4] - for i, b in enumerate(data)) - - self.sock.write(data) - - async def recv(self): - while await self.open(): - try: - fin, opcode, data = await self.read_frame() - # except (ValueError, EOFError) as ex: - except Exception as ex: - print('Exception in recv while reading frame:', ex) - await self.open(False) - return - - if not fin: - raise NotImplementedError() - - if opcode == OP_TEXT: - return data.decode('utf-8') - elif opcode == OP_BYTES: - return data - elif opcode == OP_CLOSE: - await self.open(False) - return - elif opcode == OP_PONG: - # Ignore this frame, keep waiting for a data frame - continue - elif opcode == OP_PING: - try: - # We need to send a pong frame - self.write_frame(OP_PONG, data) - - # And then continue to wait for a data frame - continue - except Exception as ex: - print('Error sending pong frame:', ex) - # If sending the pong frame fails, close the connection - await self.open(False) - return - elif opcode == OP_CONT: - # This is a continuation of a previous frame - raise NotImplementedError(opcode) - else: - raise ValueError(opcode) - - async def send(self, buf): - if not await self.open(): - return - if isinstance(buf, str): - opcode = OP_TEXT - buf = buf.encode('utf-8') - elif isinstance(buf, bytes): - opcode = OP_BYTES - else: - raise TypeError() - self.write_frame(opcode, buf) - diff --git a/draft_code/dropdown_switch.py b/draft_code/dropdown_switch.py deleted file mode 100644 index d4bfd9b1..00000000 --- a/draft_code/dropdown_switch.py +++ /dev/null @@ -1,9 +0,0 @@ -# Create a dropdown -dropdown = lv.dropdown(lv.screen_active()) -dropdown.set_options("Option 1\nOption 2\nOption 3") -dropdown.align(lv.ALIGN.CENTER, 0, 0) - - -switch = lv.switch(lv.screen_active()) -switch.center() - diff --git a/draft_code/files_to_scripts.py b/draft_code/files_to_scripts.py deleted file mode 100644 index 9d174d7a..00000000 --- a/draft_code/files_to_scripts.py +++ /dev/null @@ -1,54 +0,0 @@ -import binascii -import os -import sys - -try: - input_file = sys.argv[1] -except IndexError: - print('No file or directory given using current working directory') - input_file = os.getcwd() - -def run(in_file): - output_file = os.path.splitext(in_file)[0] + '.py' - ext = os.path.splitext(in_file)[1][1:] - - with open(in_file, 'rb') as f: - data = f.read() - - data = binascii.hexlify(data) - data = [' ' + str(data[i: min(i + 74, len(data))])[1:] for i in range(0, len(data), 74)] - data = '\n'.join(data) - - output = f'''\ -import binascii - -_{ext} = bytearray(binascii.unhexlify( -{data} -)) -{ext} = memoryview(_{ext}) -''' - - with open(output_file, 'w') as f: - f.write(output) - -def process_directory(directory): - for root, _, files in os.walk(directory): - for file in files: - file_ext = os.path.splitext(file)[1][1:] - if file_ext not in ('bmp', 'jpg', 'gif', 'png', 'bin', 'MF'): - continue - - thisfile = os.path.join(root, file) - print('found file:', thisfile) - run(thisfile) - -if os.path.isdir(input_file): - process_directory(input_file) -else: - file_ext = os.path.splitext(input_file)[1][1:] - if file_ext not in ('bmp', 'jpg', 'gif', 'png', 'bin'): - raise RuntimeError('supported image files are bmp, jpg, gif and png') - print('found file:', input_file) - run(input_file) - -print('DONE!!') diff --git a/draft_code/image_decoder.py b/draft_code/image_decoder.py deleted file mode 100644 index f8f37584..00000000 --- a/draft_code/image_decoder.py +++ /dev/null @@ -1,39 +0,0 @@ - - -import lvgl as lv - -def list_image_decoders(): - # Initialize LVGL - lv.init() - - # Start with the first decoder - first = lv.image_decoder_t() - #decoder = lv.image.decoder_get_next(first) - decoder = lv.image_decoder_t.get_next(first) - index = 0 - - # Iterate through all decoders - while decoder is not None: - print(f"Image Decoder {index}: {decoder}") - index += 1 - #decoder = lv.image.decoder_get_next(decoder) - decoder = lv.image_decoder_t.get_next(decoder) - - if index == 0: - print("No image decoders found.") - else: - print(f"Total image decoders: {index}") - -# Run the function -list_image_decoders() - - -i = lv.image(lv.screen_active()); -#i.set_src("P:/home/user/sources/MicroPythonOS/artwork/image.jpg"); -i.set_src("P:/home/user/sources/MicroPythonOS/artwork/icon_64x64.jpg"); -i.center() -h = lv.image_header_t() -i.decoder_get_info(i.image_dsc, h) -print("image info:") -print(h) -print(f"widthxheight: {h.w}x{h.h}") diff --git a/draft_code/image_tests.py b/draft_code/image_tests.py deleted file mode 100644 index 3d21261e..00000000 --- a/draft_code/image_tests.py +++ /dev/null @@ -1,42 +0,0 @@ -width=240 -height=240 - -import webcam -import time - -cam = webcam.init("/dev/video0") # Initialize webcam with device path -memview = webcam.capture_frame(cam) # Returns memoryview -time.sleep_ms(1000) -static_bytes_obj = bytes(memview) - - -image = lv.image(lv.screen_active()) -image.align(lv.ALIGN.LEFT_MID, 0, 0) -image.set_rotation(900) -# Create image descriptor once -image_dsc = lv.image_dsc_t({ - "header": { - "magic": lv.IMAGE_HEADER_MAGIC, - "w": width, - "h": height, - "stride": width , - "cf": lv.COLOR_FORMAT.L8 - }, - 'data_size': width * height, - 'data': static_bytes_obj # Will be updated per frame -}) -image.set_src(image_dsc) - -for i in range(300): - print(f"iteration {i}") - webcam.recapture_frame(cam) #refresh memview - bytes_obj = bytes(memview) - #print(f"got bytes: {len(bytes_obj)}") - #image_dsc.data = static_bytes_obj - image_dsc.data = bytes_obj - #image.set_src(image_dsc) - image.invalidate() - time.sleep_ms(10) # seems to need more than 0 or 1 ms - -print("cleanup") -webcam.deinit(cam) # Deinitializes webcam diff --git a/draft_code/include_in_build.py b/draft_code/include_in_build.py deleted file mode 100644 index bbb0fbb2..00000000 --- a/draft_code/include_in_build.py +++ /dev/null @@ -1,2 +0,0 @@ -print("This script will be included in the build.") -print("You can then run it with: import include_in_build") diff --git a/draft_code/keyboard.py b/draft_code/keyboard.py deleted file mode 100644 index 98a078b9..00000000 --- a/draft_code/keyboard.py +++ /dev/null @@ -1,46 +0,0 @@ - - -appscreen = lv.screen_active() -appscreen.clean() - -password_ta=lv.textarea(appscreen) -password_ta.set_size(200,30) -password_ta.set_one_line(True) -password_ta.align(lv.ALIGN.TOP_MID, 5, 30) -password_ta.set_text("bla") -password_ta.set_placeholder_text("Password") - -#password_ta.add_event_cb(password_ta_cb,lv.EVENT.CLICKED,None) - -#oskeyboard=lv.keyboard(appscreen) -#oskeyboard.set_size(lv.pct(100),120) -#oskeyboard.align(lv.ALIGN.BOTTOM_LEFT,0,0) -#oskeyboard.set_textarea(password_ta) - -#keyboard.add_event_cb(keyboard_cb,lv.EVENT.READY,None) -#keyboard.add_event_cb(keyboard_cb,lv.EVENT.CANCEL,None) -#keyboard.add_event_cb(keyboard_value_changed_cb,lv.EVENT.VALUE_CHANGED,None) - -#oskeyboard.add_event_cb(touch_cb, lv.EVENT.ALL, None) - - - -import sdl_keyboard -keyboard = sdl_keyboard.SDLKeyboard() - -def keyboard_cb(event): - global canvas - event_code=event.get_code() - print(f"boot_unix: code={event_code}") # target={event.get_target()}, user_data={event.get_user_data()}, param={event.get_param()} - -keyboard.add_event_cb(keyboard_cb, lv.EVENT.ALL, None) -keyboard.group.add_obj(password_ta) -#keyboard.group.add_obj(oskeyboard) - - -def touch_cb(event): - global canvas - event_code=event.get_code() - print(f"keyboard.py: code={event_code}") # target={event.get_target()}, user_data={event.get_user_data()}, param={event.get_param()} - -password_ta.add_event_cb(touch_cb, lv.EVENT.ALL, None) diff --git a/draft_code/keyboard_test.py b/draft_code/keyboard_test.py deleted file mode 100644 index 6a344028..00000000 --- a/draft_code/keyboard_test.py +++ /dev/null @@ -1,110 +0,0 @@ -# Hardware initialization for Unix and MacOS systems - -import lcd_bus -import lvgl as lv -import sdl_display -import task_handler - - -# Add lib/ to the path for modules, otherwise it will only search in ~/.micropython/lib and /usr/lib/micropython -import sys -sys.path.append('lib/') - - -import mpos.ui - - -#TFT_HOR_RES=640 -#TFT_VER_RES=480 -TFT_HOR_RES=320 -TFT_VER_RES=240 - -def window_cb(args): # doesn't get called - print(f"Window callback: {args}") - -bus = lcd_bus.SDLBus(flags=0) -bus.register_window_callback(window_cb) - -# bus.set_window_size(320,240,-1,False) # -1 might be 25 but it always becomes black, except for format 0 - -buf1 = bus.allocate_framebuffer(TFT_HOR_RES * TFT_VER_RES * 2, 0) - -display = sdl_display.SDLDisplay(data_bus=bus,display_width=TFT_HOR_RES,display_height=TFT_VER_RES,frame_buffer1=buf1,color_space=lv.COLOR_FORMAT.RGB565) -display.init() - -import sdl_pointer -mouse = sdl_pointer.SDLPointer() - -import sdl_keyboard -sdlkeyboard = sdl_keyboard.SDLKeyboard() - -#indev.set_read_cb(keypad_cb) - -# seems indev isn't properly initialized -def keypad_cb(indev, indev_data): - global sdlkeyboard - #print(f"keypad_cb {indev} {indev_data}") - #key = indev.get_key() # always 0 - #print(f"key {key}") - #key = indev_data.get("key") - #print(f"key {key}") - pressed, code = sdlkeyboard._get_key() - print(f"periodic pressed: {pressed}, code: {code}") - sdlkeyboard._read(indev, indev_data) - # I mean we could read the key and put it in the textarea but I want some kind of keypress :-/ - -sdlkeyboard._indev_drv.set_read_cb(keypad_cb) # check for escape - -def keyboard_cb(event): - event_code=event.get_code() - print(f"keyboard_test YES: code={event_code}") # target={event.get_target()}, user_data={event.get_user_data()}, param={event.get_param()} - - -def button_cb(event): - event_code=event.get_code() - name = mpos.ui.get_event_name(event_code) - print(f"button_cb YES: code={event_code} and name {name}") - -# for some reason, this text areas is receiving mouse events, and draw events, but not key events... -def ta_callback_again(event): - event_code=event.get_code() - if event_code in [19,23,25,26,27,28,29,30,49]: - return - name = mpos.ui.get_event_name(event_code) - print(f"ta_callback_again {event_code} and {name}") - #print(f"ta_callback_again: code={event_code}") # target={event.get_target()}, user_data={event.get_user_data()}, param={event.get_param()} - -sdlkeyboard.add_event_cb(keyboard_cb, lv.EVENT.ALL, None) - - -#group = lv.group_create() -#group = keyboard.get_group() - -th = task_handler.TaskHandler(duration=5) # 5ms is recommended for MicroPython+LVGL on desktop - -screen = lv.screen_active() - -b = lv.button(screen) -b.center() -b.add_event_cb(button_cb, lv.EVENT.ALL, None) -#group.add_obj(b) - -ta = lv.textarea(screen) -ta.set_one_line(True) -ta.align(lv.ALIGN.TOP_LEFT,0,0) -ta.add_event_cb(ta_callback_again, lv.EVENT.ALL, None) - -#group.add_obj(ta) - -takeyboard = lv.keyboard(screen) -takeyboard.set_textarea(ta) - - -# this does something, but just gives indev 0, being error... -#indev = lv.indev_create() -#indev.set_type(lv.INDEV_TYPE.KEYPAD) -#indev.set_read_cb(keypad_cb) # check for escape - - - -#keyboard.set_group(group) diff --git a/draft_code/keyboard_test_ai.py b/draft_code/keyboard_test_ai.py deleted file mode 100644 index a01f9d62..00000000 --- a/draft_code/keyboard_test_ai.py +++ /dev/null @@ -1,69 +0,0 @@ -import lcd_bus -import lvgl as lv -import sdl_display -import task_handler -import sys -sys.path.append('lib/') -import mpos.ui -import sdl_pointer -import sdl_keyboard - -# Display resolution -TFT_HOR_RES = 320 -TFT_VER_RES = 240 - -# Initialize display -bus = lcd_bus.SDLBus(flags=0) -buf1 = bus.allocate_framebuffer(TFT_HOR_RES * TFT_VER_RES * 2, 0) -display = sdl_display.SDLDisplay( - data_bus=bus, - display_width=TFT_HOR_RES, - display_height=TFT_VER_RES, - frame_buffer1=buf1, - color_space=lv.COLOR_FORMAT.RGB565 -) -display.init() - -# Initialize mouse -mouse = sdl_pointer.SDLPointer() - -# Initialize keyboard -keyboard = sdl_keyboard.SDLKeyboard() - -# Create group for input devices -group = lv.group_create() -keyboard.set_group(group) - - -# Create textarea -screen = lv.screen_active() -ta = lv.textarea(screen) -ta.set_one_line(True) -ta.align(lv.ALIGN.TOP_LEFT, 0, 0) -ta.set_placeholder_text("Type here") -group.add_obj(ta) - -# Optional: Debug event callback for textarea -def ta_event_cb(event): - event_code = event.get_code() - name = mpos.ui.get_event_name(event_code) - print(f"Textarea event: code={event_code}, name={name}") - -ta.add_event_cb(ta_event_cb, lv.EVENT.ALL, None) - -# Optional: Create an on-screen keyboard -keyboard_widget = lv.keyboard(screen) -keyboard_widget.set_textarea(ta) -keyboard_widget.add_flag(lv.obj.FLAG.HIDDEN) - -def ta_focus_cb(event): - event_code = event.get_code() - if event_code == lv.EVENT.FOCUSED: - keyboard_widget.clear_flag(lv.obj.FLAG.HIDDEN) - elif event_code == lv.EVENT.DEFOCUSED: - keyboard_widget.add_flag(lv.obj.FLAG.HIDDEN) - -ta.add_event_cb(ta_focus_cb, lv.EVENT.FOCUSED | lv.EVENT.DEFOCUSED, None) - -# Task handler -th = task_handler.TaskHandler(duration=5) # 5ms for desktop diff --git a/draft_code/keyboard_test_diy.py b/draft_code/keyboard_test_diy.py deleted file mode 100644 index 55b25b36..00000000 --- a/draft_code/keyboard_test_diy.py +++ /dev/null @@ -1,113 +0,0 @@ -import lcd_bus -import lvgl as lv -import sdl_display -import task_handler -import sys -sys.path.append('lib/') -import sdl_pointer -import sdl_keyboard - -# Initialize display -TFT_HOR_RES = 320 -TFT_VER_RES = 240 -bus = lcd_bus.SDLBus(flags=0) -buf1 = bus.allocate_framebuffer(TFT_HOR_RES * TFT_VER_RES * 2, 0) -display = sdl_display.SDLDisplay( - data_bus=bus, - display_width=TFT_HOR_RES, - display_height=TFT_VER_RES, - frame_buffer1=buf1, - color_space=lv.COLOR_FORMAT.RGB565 -) -display.init() - -# Initialize mouse -mouse = sdl_pointer.SDLPointer() - -# Initialize keyboard -#keyboard = sdl_keyboard.SDLKeyboard() - -pressed = False -def get_key(indev,data): - print("simulating get_key") - global pressed - if not pressed: - # input your keypad code - data.state = 1 #1 for press 0 for released - data.key=100 - #pressed = True - else: - data.state = 0 #1 for press 0 for released - data.key=100 - pressed = False - - -# Create group -group = lv.group_create() -group.set_default() - -keyboard=lv.indev_create() -keyboard.set_type(lv.INDEV_TYPE.KEYPAD) -keyboard.set_read_cb(get_key) -keyboard.set_group(group) - -#keyboard.set_group(group) - -# Create widgets -screen = lv.screen_active() - -# Textarea -ta = lv.textarea(screen) -ta.set_one_line(True) -ta.set_placeholder_text("Type here") -ta.align(lv.ALIGN.TOP_LEFT, 10, 10) -group.add_obj(ta) - -# Switch -sw = lv.switch(screen) -sw.align(lv.ALIGN.TOP_LEFT, 10, 50) -group.add_obj(sw) - -# Test Button -btn = lv.button(screen) -btn.align(lv.ALIGN.TOP_LEFT, 10, 90) -lbl = lv.label(btn) -lbl.set_text("Test Button") -group.add_obj(btn) - -# Simulate NEXT key button -btn_next = lv.button(screen) -btn_next.align(lv.ALIGN.BOTTOM_LEFT, 10, -10) -lbl_next = lv.label(btn_next) -lbl_next.set_text("NEXT") -def btn_next_cb(event): - if event.get_code() == lv.EVENT.CLICKED: - keyboard._keypad_cb(None, 1, 9, 0) # Simulate KEY_TAB (lv.KEY.NEXT) press - keyboard._keypad_cb(None, 0, 9, 0) # Simulate release -btn_next.add_event_cb(btn_next_cb, lv.EVENT.CLICKED, None) - -# Simulate ENTER key button -btn_enter = lv.button(screen) -btn_enter.align(lv.ALIGN.BOTTOM_LEFT, 100, -10) -lbl_enter = lv.label(btn_enter) -lbl_enter.set_text("ENTER") -def btn_enter_cb(event): - if event.get_code() == lv.EVENT.CLICKED: - keyboard._keypad_cb(None, 1, 13, 0) # Simulate KEY_RETURN (lv.KEY.ENTER) press - keyboard._keypad_cb(None, 0, 13, 0) # Simulate release -btn_enter.add_event_cb(btn_enter_cb, lv.EVENT.CLICKED, None) - -# Debug focus -def check_focus(): - focused = lv.group_get_focused(group) - print(f"Focused widget: {focused}") -th = task_handler.TaskHandler(duration=5) -th.register_task(check_focus, 1000) - -# Debug events -def event_cb(event, name): - event_code = event.get_code() - print(f"{name} event: code={event_code}, name={getattr(lv, 'EVENT_' + str(event_code), 'UNKNOWN')}") -ta.add_event_cb(lambda e: event_cb(e, "Textarea"), lv.EVENT.ALL, None) -sw.add_event_cb(lambda e: event_cb(e, "Switch"), lv.EVENT.ALL, None) -btn.add_event_cb(lambda e: event_cb(e, "Button"), lv.EVENT.ALL, None) diff --git a/draft_code/keyboard_test_diy_again.py b/draft_code/keyboard_test_diy_again.py deleted file mode 100644 index de50f651..00000000 --- a/draft_code/keyboard_test_diy_again.py +++ /dev/null @@ -1,121 +0,0 @@ -import lcd_bus -import lvgl as lv -import sdl_display -import task_handler -import sys -sys.path.append('lib/') -import sdl_pointer -import sdl_keyboard - -# Initialize display -TFT_HOR_RES = 320 -TFT_VER_RES = 240 -bus = lcd_bus.SDLBus(flags=0) -buf1 = bus.allocate_framebuffer(TFT_HOR_RES * TFT_VER_RES * 2, 0) -display = sdl_display.SDLDisplay( - data_bus=bus, - display_width=TFT_HOR_RES, - display_height=TFT_VER_RES, - frame_buffer1=buf1, - color_space=lv.COLOR_FORMAT.RGB565 -) -display.init() - -# Initialize mouse -mouse = sdl_pointer.SDLPointer() - -# Initialize keyboard -keyboard = sdl_keyboard.SDLKeyboard() - -# Create group -group = lv.group_create() -group.set_default() -keyboard.set_group(group) - -# Simulated key input for buttons -simulated_key = None -simulated_state = None -def get_key(indev, data): - global simulated_key, simulated_state - if simulated_key is not None: - print(f"Simulating key: state={simulated_state}, key={simulated_key}") - data.state = simulated_state - data.key = simulated_key - simulated_key = None # Clear after processing - else: - data.state = 0 # No key event by default - data.key = 0 - -# Create custom input device for simulated keys -sim_indev = lv.indev_create() -sim_indev.set_type(lv.INDEV_TYPE.KEYPAD) -sim_indev.set_read_cb(get_key) -sim_indev.set_group(group) - -# Create widgets -screen = lv.screen_active() - -# Textarea -ta = lv.textarea(screen) -ta.set_one_line(True) -ta.set_placeholder_text("Type here") -ta.align(lv.ALIGN.TOP_LEFT, 10, 10) -group.add_obj(ta) - -# Switch -sw = lv.switch(screen) -sw.align(lv.ALIGN.TOP_LEFT, 10, 50) -group.add_obj(sw) - -# Test Button -btn = lv.button(screen) -btn.align(lv.ALIGN.TOP_LEFT, 10, 90) -lbl = lv.label(btn) -lbl.set_text("Test Button") -group.add_obj(btn) - -# Simulate NEXT key button -btn_next = lv.button(screen) -btn_next.align(lv.ALIGN.BOTTOM_LEFT, 10, -10) -lbl_next = lv.label(btn_next) -lbl_next.set_text("PREV") -def btn_next_cb(event): - global simulated_key, simulated_state - if event.get_code() == lv.EVENT.CLICKED: - simulated_key = lv.KEY.PREV - simulated_state = 1 - sim_indev.read() # Trigger read immediately - simulated_state = 0 - sim_indev.read() -btn_next.add_event_cb(btn_next_cb, lv.EVENT.CLICKED, None) - -# Simulate ENTER key button -btn_enter = lv.button(screen) -btn_enter.align(lv.ALIGN.BOTTOM_LEFT, 100, -10) -lbl_enter = lv.label(btn_enter) -lbl_enter.set_text("ENTER") -def btn_enter_cb(event): - global simulated_key, simulated_state - if event.get_code() == lv.EVENT.CLICKED: - simulated_key = lv.KEY.ENTER - simulated_state = 1 - sim_indev.read() - simulated_state = 0 - sim_indev.read() -btn_enter.add_event_cb(btn_enter_cb, lv.EVENT.CLICKED, None) - -# Debug focus -def check_focus(): - focused = lv.group_get_focused(group) - print(f"Focused widget: {focused}") -th = task_handler.TaskHandler(duration=5) -th.register_task(check_focus, 1000) - -# Debug events -def event_cb(event, name): - event_code = event.get_code() - key = event.get_key() if event_code == lv.EVENT.KEY else None - print(f"{name} event: code={event_code}, name={getattr(lv, 'EVENT_' + str(event_code), 'UNKNOWN')}, key={key}") -ta.add_event_cb(lambda e: event_cb(e, "Textarea"), lv.EVENT.ALL, None) -sw.add_event_cb(lambda e: event_cb(e, "Switch"), lv.EVENT.ALL, None) -btn.add_event_cb(lambda e: event_cb(e, "Button"), lv.EVENT.ALL, None) diff --git a/draft_code/keyboard_test_diy_closer.py b/draft_code/keyboard_test_diy_closer.py deleted file mode 100644 index 67eaff70..00000000 --- a/draft_code/keyboard_test_diy_closer.py +++ /dev/null @@ -1,114 +0,0 @@ -import lcd_bus -import lvgl as lv -import sdl_display -import task_handler -import sys -sys.path.append('lib/') -import sdl_pointer -import sdl_keyboard - -# Initialize display -TFT_HOR_RES = 320 -TFT_VER_RES = 240 -bus = lcd_bus.SDLBus(flags=0) -buf1 = bus.allocate_framebuffer(TFT_HOR_RES * TFT_VER_RES * 2, 0) -display = sdl_display.SDLDisplay( - data_bus=bus, - display_width=TFT_HOR_RES, - display_height=TFT_VER_RES, - frame_buffer1=buf1, - color_space=lv.COLOR_FORMAT.RGB565 -) -display.init() - -# Initialize mouse -mouse = sdl_pointer.SDLPointer() - -# Initialize keyboard -keyboard = sdl_keyboard.SDLKeyboard() - -pressed = False -def get_key(indev,data): - print("simulating get_key") - global pressed - if not pressed: - # input your keypad code - data.state = 1 #1 for press 0 for released - data.key=100 - #pressed = True - else: - data.state = 0 #1 for press 0 for released - data.key=100 - pressed = False - - -# Create group -#group = lv.group_create() -#group.set_default() -group = keyboard.get_group() - -#keyboard=lv.indev_create() -#keyboard.set_type(lv.INDEV_TYPE.KEYPAD) -#keyboard.set_read_cb(get_key) -#keyboard.set_group(group) - -#keyboard.set_group(group) - -# Create widgets -screen = lv.screen_active() - -# Textarea -ta = lv.textarea(screen) -ta.set_one_line(True) -ta.set_placeholder_text("Type here") -ta.align(lv.ALIGN.TOP_LEFT, 10, 10) -group.add_obj(ta) - -# Switch -sw = lv.switch(screen) -sw.align(lv.ALIGN.TOP_LEFT, 10, 50) -group.add_obj(sw) - -# Test Button -btn = lv.button(screen) -btn.align(lv.ALIGN.TOP_LEFT, 10, 90) -lbl = lv.label(btn) -lbl.set_text("Test Button") -group.add_obj(btn) - -# Simulate NEXT key button -btn_next = lv.button(screen) -btn_next.align(lv.ALIGN.BOTTOM_LEFT, 10, -10) -lbl_next = lv.label(btn_next) -lbl_next.set_text("NEXT") -def btn_next_cb(event): - if event.get_code() == lv.EVENT.CLICKED: - keyboard._keypad_cb(None, 1, 9, 0) # Simulate KEY_TAB (lv.KEY.NEXT) press - keyboard._keypad_cb(None, 0, 9, 0) # Simulate release -btn_next.add_event_cb(btn_next_cb, lv.EVENT.CLICKED, None) - -# Simulate ENTER key button -btn_enter = lv.button(screen) -btn_enter.align(lv.ALIGN.BOTTOM_LEFT, 100, -10) -lbl_enter = lv.label(btn_enter) -lbl_enter.set_text("ENTER") -def btn_enter_cb(event): - if event.get_code() == lv.EVENT.CLICKED: - keyboard._keypad_cb(None, 1, 13, 0) # Simulate KEY_RETURN (lv.KEY.ENTER) press - keyboard._keypad_cb(None, 0, 13, 0) # Simulate release -btn_enter.add_event_cb(btn_enter_cb, lv.EVENT.CLICKED, None) - -# Debug focus -def check_focus(): - focused = lv.group_get_focused(group) - print(f"Focused widget: {focused}") -th = task_handler.TaskHandler(duration=5) -th.register_task(check_focus, 1000) - -# Debug events -def event_cb(event, name): - event_code = event.get_code() - print(f"{name} event: code={event_code}, name={getattr(lv, 'EVENT_' + str(event_code), 'UNKNOWN')}") -ta.add_event_cb(lambda e: event_cb(e, "Textarea"), lv.EVENT.ALL, None) -sw.add_event_cb(lambda e: event_cb(e, "Switch"), lv.EVENT.ALL, None) -btn.add_event_cb(lambda e: event_cb(e, "Button"), lv.EVENT.ALL, None) diff --git a/draft_code/keyboard_test_diy_closer_works.py b/draft_code/keyboard_test_diy_closer_works.py deleted file mode 100644 index 67eaff70..00000000 --- a/draft_code/keyboard_test_diy_closer_works.py +++ /dev/null @@ -1,114 +0,0 @@ -import lcd_bus -import lvgl as lv -import sdl_display -import task_handler -import sys -sys.path.append('lib/') -import sdl_pointer -import sdl_keyboard - -# Initialize display -TFT_HOR_RES = 320 -TFT_VER_RES = 240 -bus = lcd_bus.SDLBus(flags=0) -buf1 = bus.allocate_framebuffer(TFT_HOR_RES * TFT_VER_RES * 2, 0) -display = sdl_display.SDLDisplay( - data_bus=bus, - display_width=TFT_HOR_RES, - display_height=TFT_VER_RES, - frame_buffer1=buf1, - color_space=lv.COLOR_FORMAT.RGB565 -) -display.init() - -# Initialize mouse -mouse = sdl_pointer.SDLPointer() - -# Initialize keyboard -keyboard = sdl_keyboard.SDLKeyboard() - -pressed = False -def get_key(indev,data): - print("simulating get_key") - global pressed - if not pressed: - # input your keypad code - data.state = 1 #1 for press 0 for released - data.key=100 - #pressed = True - else: - data.state = 0 #1 for press 0 for released - data.key=100 - pressed = False - - -# Create group -#group = lv.group_create() -#group.set_default() -group = keyboard.get_group() - -#keyboard=lv.indev_create() -#keyboard.set_type(lv.INDEV_TYPE.KEYPAD) -#keyboard.set_read_cb(get_key) -#keyboard.set_group(group) - -#keyboard.set_group(group) - -# Create widgets -screen = lv.screen_active() - -# Textarea -ta = lv.textarea(screen) -ta.set_one_line(True) -ta.set_placeholder_text("Type here") -ta.align(lv.ALIGN.TOP_LEFT, 10, 10) -group.add_obj(ta) - -# Switch -sw = lv.switch(screen) -sw.align(lv.ALIGN.TOP_LEFT, 10, 50) -group.add_obj(sw) - -# Test Button -btn = lv.button(screen) -btn.align(lv.ALIGN.TOP_LEFT, 10, 90) -lbl = lv.label(btn) -lbl.set_text("Test Button") -group.add_obj(btn) - -# Simulate NEXT key button -btn_next = lv.button(screen) -btn_next.align(lv.ALIGN.BOTTOM_LEFT, 10, -10) -lbl_next = lv.label(btn_next) -lbl_next.set_text("NEXT") -def btn_next_cb(event): - if event.get_code() == lv.EVENT.CLICKED: - keyboard._keypad_cb(None, 1, 9, 0) # Simulate KEY_TAB (lv.KEY.NEXT) press - keyboard._keypad_cb(None, 0, 9, 0) # Simulate release -btn_next.add_event_cb(btn_next_cb, lv.EVENT.CLICKED, None) - -# Simulate ENTER key button -btn_enter = lv.button(screen) -btn_enter.align(lv.ALIGN.BOTTOM_LEFT, 100, -10) -lbl_enter = lv.label(btn_enter) -lbl_enter.set_text("ENTER") -def btn_enter_cb(event): - if event.get_code() == lv.EVENT.CLICKED: - keyboard._keypad_cb(None, 1, 13, 0) # Simulate KEY_RETURN (lv.KEY.ENTER) press - keyboard._keypad_cb(None, 0, 13, 0) # Simulate release -btn_enter.add_event_cb(btn_enter_cb, lv.EVENT.CLICKED, None) - -# Debug focus -def check_focus(): - focused = lv.group_get_focused(group) - print(f"Focused widget: {focused}") -th = task_handler.TaskHandler(duration=5) -th.register_task(check_focus, 1000) - -# Debug events -def event_cb(event, name): - event_code = event.get_code() - print(f"{name} event: code={event_code}, name={getattr(lv, 'EVENT_' + str(event_code), 'UNKNOWN')}") -ta.add_event_cb(lambda e: event_cb(e, "Textarea"), lv.EVENT.ALL, None) -sw.add_event_cb(lambda e: event_cb(e, "Switch"), lv.EVENT.ALL, None) -btn.add_event_cb(lambda e: event_cb(e, "Button"), lv.EVENT.ALL, None) diff --git a/draft_code/keyboard_test_onscreen.py b/draft_code/keyboard_test_onscreen.py deleted file mode 100644 index cc436ec0..00000000 --- a/draft_code/keyboard_test_onscreen.py +++ /dev/null @@ -1,103 +0,0 @@ -import lcd_bus -import lvgl as lv -import sdl_display -import task_handler -import sys -sys.path.append('lib/') -import sdl_pointer -import sdl_keyboard - -# Initialize display -TFT_HOR_RES = 320 -TFT_VER_RES = 240 -bus = lcd_bus.SDLBus(flags=0) -buf1 = bus.allocate_framebuffer(TFT_HOR_RES * TFT_VER_RES * 2, 0) -display = sdl_display.SDLDisplay( - data_bus=bus, - display_width=TFT_HOR_RES, - display_height=TFT_VER_RES, - frame_buffer1=buf1, - color_space=lv.COLOR_FORMAT.RGB565 -) -display.init() - -# Initialize mouse -mouse = sdl_pointer.SDLPointer() - -# Initialize keyboard -keyboard = sdl_keyboard.SDLKeyboard() - -# Create group -group = lv.group_create() -group.set_default() # Set as default group -keyboard.set_group(group) - -# Create widgets -screen = lv.screen_active() - -# Textarea -ta = lv.textarea(screen) -ta.set_one_line(True) -ta.set_placeholder_text("Type here") -ta.align(lv.ALIGN.TOP_LEFT, 10, 10) -group.add_obj(ta) - -# Switch -sw = lv.switch(screen) -sw.align(lv.ALIGN.TOP_LEFT, 10, 50) -group.add_obj(sw) - -# Button -btn = lv.button(screen) -btn.align(lv.ALIGN.TOP_LEFT, 10, 90) -lbl = lv.label(btn) -lbl.set_text("Test Button") -group.add_obj(btn) - -# Simulate NEXT key button -btn_next = lv.button(screen) -btn_next.align(lv.ALIGN.BOTTOM_LEFT, 10, -10) -lbl_next = lv.label(btn_next) -lbl_next.set_text("NEXT") -def btn_next_cb(event): - if event.get_code() == lv.EVENT.CLICKED: - keyboard.send_event(lv.EVENT.KEY, lv.KEY.NEXT) -btn_next.add_event_cb(btn_next_cb, lv.EVENT.CLICKED, None) - -# Simulate ENTER key button -btn_enter = lv.button(screen) -btn_enter.align(lv.ALIGN.BOTTOM_LEFT, 100, -10) -lbl_enter = lv.label(btn_enter) -lbl_enter.set_text("ENTER") -def btn_enter_cb(event): - if event.get_code() == lv.EVENT.CLICKED: - keyboard.send_event(lv.EVENT.KEY, lv.KEY.ENTER) -btn_enter.add_event_cb(btn_enter_cb, lv.EVENT.CLICKED, None) - -# Debug focus -def check_focus(): - focused = lv.group_get_focused(group) - print(f"Focused widget: {focused}") -th = task_handler.TaskHandler(duration=5) -th.register_task(check_focus, 1000) # Check focus every 1s - -# Debug textarea events -def ta_event_cb(event): - event_code = event.get_code() - name = getattr(lv, 'EVENT_' + str(event_code), 'UNKNOWN') - print(f"Textarea event: code={event_code}, name={name}") -ta.add_event_cb(ta_event_cb, lv.EVENT.ALL, None) - -# Debug switch events -def sw_event_cb(event): - event_code = event.get_code() - name = getattr(lv, 'EVENT_' + str(event_code), 'UNKNOWN') - print(f"Switch event: code={event_code}, name={name}") -sw.add_event_cb(sw_event_cb, lv.EVENT.ALL, None) - -# Debug button events -def btn_event_cb(event): - event_code = event.get_code() - name = getattr(lv, 'EVENT_' + str(event_code), 'UNKNOWN') - print(f"Button event: code={event_code}, name={name}") -btn.add_event_cb(btn_event_cb, lv.EVENT.ALL, None) diff --git a/draft_code/keyboard_test_onscreen_again.py b/draft_code/keyboard_test_onscreen_again.py deleted file mode 100644 index 65e294ed..00000000 --- a/draft_code/keyboard_test_onscreen_again.py +++ /dev/null @@ -1,92 +0,0 @@ -import lcd_bus -import lvgl as lv -import sdl_display -import task_handler -import sys -sys.path.append('lib/') -import sdl_pointer -import sdl_keyboard - -# Initialize display -TFT_HOR_RES = 320 -TFT_VER_RES = 240 -bus = lcd_bus.SDLBus(flags=0) -buf1 = bus.allocate_framebuffer(TFT_HOR_RES * TFT_VER_RES * 2, 0) -display = sdl_display.SDLDisplay( - data_bus=bus, - display_width=TFT_HOR_RES, - display_height=TFT_VER_RES, - frame_buffer1=buf1, - color_space=lv.COLOR_FORMAT.RGB565 -) -display.init() - -# Initialize mouse -mouse = sdl_pointer.SDLPointer() - -# Initialize keyboard -keyboard = sdl_keyboard.SDLKeyboard() - -# Create group -group = lv.group_create() -group.set_default() -keyboard.set_group(group) - -# Create widgets -screen = lv.screen_active() - -# Textarea -ta = lv.textarea(screen) -ta.set_one_line(True) -ta.set_placeholder_text("Type here") -ta.align(lv.ALIGN.TOP_LEFT, 10, 10) -group.add_obj(ta) - -# Switch -sw = lv.switch(screen) -sw.align(lv.ALIGN.TOP_LEFT, 10, 50) -group.add_obj(sw) - -# Test Button -btn = lv.button(screen) -btn.align(lv.ALIGN.TOP_LEFT, 10, 90) -lbl = lv.label(btn) -lbl.set_text("Test Button") -group.add_obj(btn) - -# Simulate NEXT key button -btn_next = lv.button(screen) -btn_next.align(lv.ALIGN.BOTTOM_LEFT, 10, -10) -lbl_next = lv.label(btn_next) -lbl_next.set_text("NEXT") -def btn_next_cb(event): - if event.get_code() == lv.EVENT.CLICKED: - keyboard._keypad_cb(None, 1, 9, 0) # Simulate KEY_TAB (lv.KEY.NEXT) press - keyboard._keypad_cb(None, 0, 9, 0) # Simulate release -btn_next.add_event_cb(btn_next_cb, lv.EVENT.CLICKED, None) - -# Simulate ENTER key button -btn_enter = lv.button(screen) -btn_enter.align(lv.ALIGN.BOTTOM_LEFT, 100, -10) -lbl_enter = lv.label(btn_enter) -lbl_enter.set_text("ENTER") -def btn_enter_cb(event): - if event.get_code() == lv.EVENT.CLICKED: - keyboard._keypad_cb(None, 1, 13, 0) # Simulate KEY_RETURN (lv.KEY.ENTER) press - keyboard._keypad_cb(None, 0, 13, 0) # Simulate release -btn_enter.add_event_cb(btn_enter_cb, lv.EVENT.CLICKED, None) - -# Debug focus -def check_focus(): - focused = lv.group_get_focused(group) - print(f"Focused widget: {focused}") -th = task_handler.TaskHandler(duration=5) -th.register_task(check_focus, 1000) - -# Debug events -def event_cb(event, name): - event_code = event.get_code() - print(f"{name} event: code={event_code}, name={getattr(lv, 'EVENT_' + str(event_code), 'UNKNOWN')}") -ta.add_event_cb(lambda e: event_cb(e, "Textarea"), lv.EVENT.ALL, None) -sw.add_event_cb(lambda e: event_cb(e, "Switch"), lv.EVENT.ALL, None) -btn.add_event_cb(lambda e: event_cb(e, "Button"), lv.EVENT.ALL, None) diff --git a/draft_code/keyboard_test_works_simplify.py b/draft_code/keyboard_test_works_simplify.py deleted file mode 100644 index 90f48a38..00000000 --- a/draft_code/keyboard_test_works_simplify.py +++ /dev/null @@ -1,103 +0,0 @@ -# Hardware initialization for Unix and MacOS systems - -import lcd_bus -import lvgl as lv -import sdl_display -import task_handler - - -# Add lib/ to the path for modules, otherwise it will only search in ~/.micropython/lib and /usr/lib/micropython -import sys -sys.path.append('lib/') - - -import mpos.ui - - -#TFT_HOR_RES=640 -#TFT_VER_RES=480 -TFT_HOR_RES=320 -TFT_VER_RES=240 - -def window_cb(args): # doesn't get called - print(f"Window callback: {args}") - -bus = lcd_bus.SDLBus(flags=0) -bus.register_window_callback(window_cb) - -# bus.set_window_size(320,240,-1,False) # -1 might be 25 but it always becomes black, except for format 0 - -buf1 = bus.allocate_framebuffer(TFT_HOR_RES * TFT_VER_RES * 2, 0) - -display = sdl_display.SDLDisplay(data_bus=bus,display_width=TFT_HOR_RES,display_height=TFT_VER_RES,frame_buffer1=buf1,color_space=lv.COLOR_FORMAT.RGB565) -display.init() - -import sdl_pointer -mouse = sdl_pointer.SDLPointer() - -import sdl_keyboard -keyboard = sdl_keyboard.SDLKeyboard() - -# seems indev isn't properly initialized -def keypad_cb(indev, indev_data): - #print(f"keypad_cb {indev} {indev_data}") - #key = indev.get_key() # always 0 - #print(f"key {key}") - #key = indev_data.get("key") - #print(f"key {key}") - pressed, code = keyboard._get_key() - print(f"periodic pressed: {pressed}, code: {code}") - # I mean we could read the key and put it in the textarea but I want some kind of keypress :-/ - -def keyboard_cb(event): - event_code=event.get_code() - print(f"keyboard_test YES: code={event_code}") # target={event.get_target()}, user_data={event.get_user_data()}, param={event.get_param()} - - -def button_cb(event): - event_code=event.get_code() - name = mpos.ui.get_event_name(event_code) - print(f"button_cb YES: code={event_code} and name {name}") - -# for some reason, this text areas is receiving mouse events, and draw events, but not key events... -def ta_callback_again(event): - event_code=event.get_code() - if event_code in [19,23,25,26,27,28,29,30,49]: - return - name = mpos.ui.get_event_name(event_code) - print(f"ta_callback_again {event_code} and {name}") - #print(f"ta_callback_again: code={event_code}") # target={event.get_target()}, user_data={event.get_user_data()}, param={event.get_param()} - -keyboard.add_event_cb(keyboard_cb, lv.EVENT.ALL, None) - - -#group = lv.group_create() -#group = keyboard.get_group() - -th = task_handler.TaskHandler(duration=5) # 5ms is recommended for MicroPython+LVGL on desktop - -screen = lv.screen_active() - -b = lv.button(screen) -b.center() -b.add_event_cb(button_cb, lv.EVENT.ALL, None) -#group.add_obj(b) - -ta = lv.textarea(screen) -ta.set_one_line(True) -ta.align(lv.ALIGN.TOP_LEFT,0,0) -#group.add_obj(ta) - -keyboard = lv.keyboard(screen) -keyboard.set_textarea(ta) - - -# this does something, but just gives indev 0, being error... -#indev = lv.indev_create() -#indev.set_type(lv.INDEV_TYPE.KEYPAD) -#indev.set_read_cb(keypad_cb) - -ta.add_event_cb(ta_callback_again, lv.EVENT.ALL, None) - - -#keyboard.set_group(group) diff --git a/draft_code/main.c_with_chroot b/draft_code/main.c_with_chroot deleted file mode 100644 index 426b7078..00000000 --- a/draft_code/main.c_with_chroot +++ /dev/null @@ -1,81 +0,0 @@ -diff --git a/ports/unix/main.c b/ports/unix/main.c -index 58fa3ff..c022c20 100644 ---- a/ports/unix/main.c -+++ b/ports/unix/main.c -@@ -53,6 +53,8 @@ - #include "extmod/vfs_posix.h" - #include "genhdr/mpversion.h" - #include "input.h" -+#include "machine_sdl.h" -+#include "machine_timer.h" - - // Command line options, with their defaults - static bool compile_only = false; -@@ -61,7 +63,7 @@ static uint emit_opt = MP_EMIT_OPT_NONE; - #if MICROPY_ENABLE_GC - // Heap size of GC heap (if enabled) - // Make it larger on a 64 bit machine, because pointers are larger. --long heap_size = 1024 * 1024 * (sizeof(mp_uint_t) / 4); -+long heap_size = 8388608; - #endif - - // Number of heaps to assign by default if MICROPY_GC_SPLIT_HEAP=1 -@@ -192,6 +194,12 @@ static char *strjoin(const char *s1, int sep_char, const char *s2) { - } - #endif - -+char *mp_repl_get_ps3(void) -+{ -+ return ""; -+} -+ -+ - static int do_repl(void) { - mp_hal_stdout_tx_str(MICROPY_BANNER_NAME_AND_VERSION); - mp_hal_stdout_tx_str("; " MICROPY_BANNER_MACHINE); -@@ -282,8 +290,16 @@ static int do_repl(void) { - for (;;) { - char *line = prompt((char *)mp_repl_get_ps1()); - if (line == NULL) { -- // EOF -- return 0; -+ if (errno != EWOULDBLOCK) { -+ return 0; -+ } else { -+ while (line == NULL && errno == EWOULDBLOCK) { -+ mp_handle_pending(true); -+ usleep(1000); -+ line = prompt(mp_repl_get_ps3()); -+ } -+ if (line == NULL) return 0; -+ } - } - while (mp_repl_continue_with_input(line)) { - char *line2 = prompt((char *)mp_repl_get_ps2()); -@@ -470,6 +486,17 @@ static void sys_set_excecutable(char *argv0) { - MP_NOINLINE int main_(int argc, char **argv); - - int main(int argc, char **argv) { -+ // Parse command-line arguments for a custom root -+ const char *fs_root = "/home/user/sources/PiggyOS/internal_filesystem"; // Hardcode or parse from argv -+ if (chroot(fs_root) != 0) { -+ perror("chroot failed"); -+ return 1; -+ } -+ if (chdir("/") != 0) { -+ perror("chdir failed"); -+ return 1; -+ } -+ - #if MICROPY_PY_THREAD - mp_thread_init(); - #endif -@@ -752,6 +779,8 @@ MP_NOINLINE int main_(int argc, char **argv) { - MP_STATE_THREAD(prof_trace_callback) = MP_OBJ_NULL; - #endif - -+ machine_timer_deinit_all(); -+ deinit_sdl(); - #if MICROPY_PY_SYS_ATEXIT - // Beware, the sys.settrace callback should be disabled before running sys.atexit. - if (mp_obj_is_callable(MP_STATE_VM(sys_exitfunc))) { diff --git a/draft_code/microdot_webserver.py b/draft_code/microdot_webserver.py deleted file mode 100644 index 3a030501..00000000 --- a/draft_code/microdot_webserver.py +++ /dev/null @@ -1,114 +0,0 @@ - - - -#import mip -#mip.install('github:miguelgrinberg/microdot/src/microdot/microdot.py') -# http://192.168.1.122/upload -# http://192.168.1.122/files// - - -from microdot import Microdot, Response -import os - - -# HTML template for the upload form -UPLOAD_FORM = ''' - - -File Manager - -

File Manager

-

View Files

-

Upload File

-
- - -
- - -''' - -app = Microdot() - -@app.route('/') -async def index(request): - return 'Files' - - -@app.route('/files/') -async def list_files(req, path=''): - try: - # Sanitize path to prevent directory traversal - path = path.strip('/') - if '..' in path: - return Response('Invalid path', status_code=400) - # Get directory contents - full_path = '/' + path - files = os.listdir(full_path) if path else os.listdir('/') - html = '

File Manager

    ' - for f in files: - link_path = f'{path}/{f}' if path else f - html += f'
  • {f} | Download
  • ' - html += '
' - return Response(html, headers={'Content-Type': 'text/html'}) - except OSError as e: - return Response(f'Error: {e}', status_code=500) - - -@app.route('/download/') -async def download_file(req, path): - try: - full_path = '/' + path.strip('/') - with open(full_path, 'rb') as f: - content = f.read() # Read in chunks for large files - return Response(content, headers={ - 'Content-Type': 'application/octet-stream', - 'Content-Disposition': f'attachment; filename="{path.split("/")[-1]}"' - }) - except OSError as e: - return Response(f'Error: {e}', status_code=404) - - - -@app.route('/upload', methods=['GET']) -async def upload_form(req): - return Response(UPLOAD_FORM, headers={'Content-Type': 'text/html'}) - - - -@app.route('/upload', methods=['POST']) -async def upload_file(req): - try: - # Check if form data contains a file - if 'file' not in req.form or not req.files['file']['filename']: - return Response('No file selected', status_code=400) - # Get file details - filename = req.files['file']['filename'] - file_content = req.files['file']['body'] - # Sanitize filename to prevent path traversal - filename = filename.split('/')[-1].split('\\')[-1] - if not filename: - return Response('Invalid filename', status_code=400) - # Save file to filesystem - file_path = f'/{filename}' - with open(file_path, 'wb') as f: - f.write(file_content) # Write in one go for small files - # Free memory - gc.collect() - # Redirect to file listing - return Response(status_code=302, headers={'Location': '/files'}) - except OSError as e: - return Response(f'Error saving file: {e}', status_code=500) - except MemoryError: - return Response('File too large for available memory', status_code=507) - - - -def startit(): - app.run(port=80) - # http://192.168.1.115:5000 - - -import _thread -_thread.start_new_thread(startit, ()) - diff --git a/draft_code/micropython_async_websocket_client_test.py b/draft_code/micropython_async_websocket_client_test.py deleted file mode 100644 index e14b0d14..00000000 --- a/draft_code/micropython_async_websocket_client_test.py +++ /dev/null @@ -1,52 +0,0 @@ -# test of https://github.com/Vovaman/micropython_async_websocket_client/ -# install with mip - -import socket -import asyncio as a -import binascii as b -import random as r -from collections import namedtuple -import re -import struct -import ssl - -from ws import AsyncWebsocketClient - -async def websocket_example(): - # Initialize the WebSocket client - aws = AsyncWebsocketClient(ms_delay_for_read=10) - - try: - # Connect to echo.websocket.events - await aws.handshake("wss://echo.websocket.events") - print("Connected to WebSocket server") - - # Send a test message - test_message = "Hello, WebSocket!" - print(f"Sending: {test_message}") - await aws.send(test_message) - - # Receive the echoed response - response = await aws.recv() - print(f"Received: {response}") - - # Send a ping - aws.write_frame(ws.OP_PING, b"ping") - print("Sent ping") - - # Wait for pong or other messages - response = await aws.recv() - if response is None: - print("Received pong or connection closed") - else: - print(f"Received: {response}") - - except Exception as e: - print(f"Error: {e}") - finally: - # Clean up - await aws.close() - print("Connection closed") - -# Run the example -a.run(websocket_example()) diff --git a/draft_code/modwebsocket_test.py b/draft_code/modwebsocket_test.py deleted file mode 100644 index 84bd3f87..00000000 --- a/draft_code/modwebsocket_test.py +++ /dev/null @@ -1,116 +0,0 @@ -import socket -import ssl -import ubinascii -from websocket import websocket -import select - -# Resolve hostname -host = 'ws.postman-echo.com' -port = 443 -handshake_path = '/raw' -# Option: echo.websocket.events (unreliable) -#host = 'echo.websocket.events' -#handshake_path = '/' - -try: - addr_info = socket.getaddrinfo(host, port)[0][-1] - print('Resolved address:', addr_info) -except Exception as e: - print('DNS resolution failed:', e) - raise - -# Create and connect socket -sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) -try: - sock.connect(addr_info) - print('Socket connected') -except Exception as e: - print('Connect failed:', e) - sock.close() - raise - -# Wrap socket with SSL -try: - ssl_sock = ssl.wrap_socket(sock, server_hostname=host) - print('SSL connection established') -except Exception as e: - print('SSL wrap failed:', e) - sock.close() - raise - -# Set socket to non-blocking -ssl_sock.setblocking(False) - -# Perform WebSocket handshake -key = ubinascii.b2a_base64(b'random_bytes_here').strip() -handshake = ( - 'GET {} HTTP/1.1\r\n' - 'Host: {}\r\n' - 'Upgrade: websocket\r\n' - 'Connection: Upgrade\r\n' - 'Sec-WebSocket-Key: {}\r\n' - 'Sec-WebSocket-Version: 13\r\n' - '\r\n' -).format(handshake_path, host, key.decode()) - -try: - ssl_sock.write(handshake.encode()) - print('Handshake sent') -except Exception as e: - print('Failed to send handshake:', e) - ssl_sock.close() - raise - -# Read HTTP response until \r\n\r\n -response_bytes = bytearray() -poller = select.poll() -poller.register(ssl_sock, select.POLLIN) -max_polls = 50 # 5s timeout (50 * 100ms) -for poll_count in range(max_polls): - if poller.poll(100): - chunk = ssl_sock.read(128) - if chunk is None: - continue - if not chunk: - break - response_bytes.extend(chunk) - if b'\r\n\r\n' in response_bytes: - http_response_bytes = response_bytes[:response_bytes.find(b'\r\n\r\n') + 4] - try: - response = http_response_bytes.decode('utf-8') - if '101 Switching Protocols' not in response: - raise Exception('Handshake failed') - print('Handshake successful') - break - except UnicodeError as e: - print('UnicodeError:', e) - ssl_sock.close() - raise Exception('Failed to decode HTTP response') - else: - continue -else: - ssl_sock.close() - print('Handshake timeout: No response received after {} seconds ({} bytes received)'.format(max_polls * 0.1, len(response_bytes))) - raise Exception('Handshake timeout') - -# Create WebSocket object -ws = websocket(ssl_sock, True) -print('WebSocket object created') - -# Send and receive data -ws.write('Hello, Secure WebSocket!') -max_attempts = 5 -for attempt in range(max_attempts): - if poller.poll(100): - data = ws.read(1024) - if data: - print('Received:', data) - break - else: - print('Read attempt', attempt + 1, 'no data') -else: - print('Read timeout: No response received after {} attempts ({} seconds)'.format(max_attempts, max_attempts * 0.1)) - -# Close connection -ws.close() -print('Connection closed') diff --git a/draft_code/modwebsocket_test_workaround_mask_key.py b/draft_code/modwebsocket_test_workaround_mask_key.py deleted file mode 100644 index 29014014..00000000 --- a/draft_code/modwebsocket_test_workaround_mask_key.py +++ /dev/null @@ -1,201 +0,0 @@ -import socket -import ssl -import ubinascii -from websocket import websocket -import select -import urandom - -# Function to send a masked WebSocket text frame -def ws_send_text(sock, message): - data = message.encode() - length = len(data) - - frame = bytearray() - frame.append(0x81) # FIN=1, opcode=0x1 (text) - mask_bit = 0x80 - mask_key = bytearray(urandom.getrandbits(32).to_bytes(4, 'big')) - - if length <= 125: - frame.append(mask_bit | length) - elif length <= 65535: - frame.append(mask_bit | 126) - frame.extend(length.to_bytes(2, 'big')) - else: - frame.append(mask_bit | 127) - frame.extend(length.to_bytes(8, 'big')) - - frame.extend(mask_key) - masked_data = bytearray(data) - for i in range(len(data)): - masked_data[i] ^= mask_key[i % 4] - frame.extend(masked_data) - return sock.write(frame) - -# Resolve hostname -host = 'echo.websocket.events' -port = 443 -handshake_path = '/' # Matches aiohttp example -# Fallback: ws.postman-echo.com -host = 'ws.postman-echo.com' -handshake_path = '/raw' - -try: - addr_info = socket.getaddrinfo(host, port)[0][-1] - print('Resolved address:', addr_info) -except Exception as e: - print('DNS resolution failed:', e) - raise - -# Create and connect socket -sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) -try: - sock.connect(addr_info) - print('Socket connected') -except Exception as e: - print('Connect failed:', e) - sock.close() - raise - -# Wrap socket with SSL -try: - ssl_sock = ssl.wrap_socket(sock, server_hostname=host) - print('SSL connection established') - print('SSL cipher:', ssl_sock.cipher()) -except Exception as e: - print('SSL wrap failed:', e) - sock.close() - raise - -# Set socket to non-blocking -ssl_sock.setblocking(False) - -# Perform WebSocket handshake -key = ubinascii.b2a_base64(b'random_bytes_here').strip() -handshake = ( - 'GET {} HTTP/1.1\r\n' - 'Host: {}\r\n' - 'Upgrade: websocket\r\n' - 'Connection: Upgrade\r\n' - 'Sec-WebSocket-Key: {}\r\n' - 'Sec-WebSocket-Version: 13\r\n' - '\r\n' -).format(handshake_path, host, key.decode()) - -try: - bytes_written = ssl_sock.write(handshake.encode()) - print('Handshake sent, bytes written:', bytes_written) -except Exception as e: - print('Failed to send handshake:', e) - ssl_sock.close() - raise - -# Read HTTP response until \r\n\r\n -response_bytes = bytearray() -poller = select.poll() -poller.register(ssl_sock, select.POLLIN) -max_polls = 100 # 10s timeout (100 * 100ms) -for poll_count in range(max_polls): - events = poller.poll(100) - print('Poll', poll_count + 1, 'events:', events) - if events: - chunk = ssl_sock.read(128) - if chunk is None: - print('Read returned None, continuing') - continue - if not chunk: - print('No more data received (EOF)') - break - response_bytes.extend(chunk) - print('Received chunk, length:', len(chunk)) - if b'\r\n\r\n' in response_bytes: - http_response_bytes = response_bytes[:response_bytes.find(b'\r\n\r\n') + 4] - try: - response = http_response_bytes.decode('utf-8') - if '101 Switching Protocols' not in response: - raise Exception('Handshake failed') - print('Handshake successful') - break - except UnicodeError as e: - print('UnicodeError:', e) - ssl_sock.close() - raise Exception('Failed to decode HTTP response') - else: - print('Poll', poll_count + 1, 'no data') -else: - ssl_sock.close() - print('Handshake timeout: No response received after {} seconds ({} bytes received)'.format(max_polls * 0.1, len(response_bytes))) - raise Exception('Handshake timeout') - -# Create WebSocket object -ws = websocket(ssl_sock, True) -print('WebSocket object created') - -# Send and receive data -try: - # This doesn't work because the websocket module fails to set the mask bit - # and apply a random 4-byte mask key as required by the WebSocket protocol - # for client-to-server frames, causing the server to close the connection - # with an "incorrect mask flag" error (status code 1002). - # bytes_written = ws.write('hello world!\r\n') - # print('Sent message, bytes written:', bytes_written) - - # Proper, working code using manual frame masking - bytes_written = ws_send_text(ssl_sock, 'hello world!\r\n') - print('Sent message, bytes written:', bytes_written) -except Exception as e: - print('Failed to send message:', e) - ws.close() - raise - -# Debug: Read raw socket data -try: - events = poller.poll(500) - if events: - raw_data = ssl_sock.read(1024) - print('Raw socket data:', raw_data) - if raw_data: - print('Raw socket data hex:', raw_data.hex()) - else: - print('No raw socket data available') -except Exception as e: - print('Raw socket read error:', e) - -# Read WebSocket messages -max_attempts = 5 # Reduced to 5 attempts (2.5s with 500ms polls) -for attempt in range(max_attempts): - events = poller.poll(500) - print('Read poll attempt', attempt + 1, 'events:', events) - if events: - try: - data = ws.read(1024) - if data is None: - print('Read attempt', attempt + 1, 'returned None') - continue - print('Read attempt', attempt + 1, 'received:', data) - if data: - continue # Keep reading for more messages - except Exception as e: - print('Read attempt', attempt + 1, 'error:', e) - else: - print('Read attempt', attempt + 1, 'no data') -else: - print('Read timeout: No response received after {} attempts ({} seconds)'.format(max_attempts, max_attempts * 0.5)) - -# Send close message -try: - # This doesn't work because the websocket module fails to set the mask bit - # and apply a random 4-byte mask key as required by the WebSocket protocol - # for client-to-server frames, causing the server to close the connection - # with an "incorrect mask flag" error (status code 1002). - # bytes_written = ws.write('close\r\n') - # print('Sent close, bytes written:', bytes_written) - - # Proper, working code using manual frame masking - bytes_written = ws_send_text(ssl_sock, 'close\r\n') - print('Sent close, bytes written:', bytes_written) -except Exception as e: - print('Failed to send close:', e) - -# Close connection -ws.close() -print('Connection closed') diff --git a/draft_code/my_websocket_test.py b/draft_code/my_websocket_test.py deleted file mode 100644 index 73e2b4df..00000000 --- a/draft_code/my_websocket_test.py +++ /dev/null @@ -1,49 +0,0 @@ -# it's not super fast but it works! - -import websocket -import _thread -import time - -def on_message(wsapp, message): - print(f"got message: {message}") - -def on_ping(wsapp, message): - print("Got a ping! A pong reply has already been automatically sent.") - -def on_pong(wsapp, message): - print("Got a pong! No need to respond") - - -def on_error(wsapp, message): - print(f"Got error: {message}") - - -#wsapp = websocket.WebSocketApp("wss://testnet.binance.vision/ws/btcusdt@trade", on_message=on_message, on_ping=on_ping, on_pong=on_pong, on_error=on_error) - -wsapp = websocket.WebSocketApp("wss://echo.websocket.events", on_message=on_message, on_ping=on_ping, on_pong=on_pong, on_error=on_error) - -def stress_test_thread(): - print("before run_forever") - wsapp.run_forever(ping_interval=15, ping_timeout=10, ping_payload="This is an optional ping payload") - print("after run_forever") - -_thread.stack_size(16*1024) -_thread.start_new_thread(stress_test_thread, ()) - -time.sleep(5) -print("sending ok") -wsapp.send_text('ok') - - -time.sleep(15) -print("sending again") -wsapp.send_text('again') - - -time.sleep(25) -print("sending more") -wsapp.send_text('more') - -wsapp.close() - - diff --git a/draft_code/nostr_receive.py b/draft_code/nostr_receive.py deleted file mode 100644 index 16de48cc..00000000 --- a/draft_code/nostr_receive.py +++ /dev/null @@ -1,110 +0,0 @@ -import json -import ssl -import time -import _thread - -from nostr.filter import Filter, Filters -from nostr.event import Event, EventKind -from nostr.relay_manager import RelayManager -from nostr.message_type import ClientMessageType - -#filters = Filters([Filter(authors=[], kinds=[EventKind.TEXT_NOTE])]) -#filters = Filters([Filter(authors=["181137054fe60df5168976311f0bf44dbe4bd4d2e0af69325dfee9fa81a8cbda"], kinds=[EventKind.TEXT_NOTE])]) -#timestamp = round(time.time()-50) -#timestamp = round(time.time()) # going for zero events to check memory use - -timetogoback = 1000 -timetogoback = 2419200 # 28 days -timetogoback = 7776000 # 3 months - -# event_msg: pubkey: 181137054fe60df5168976311f0bf44dbe4bd4d2e0af69325dfee9fa81a8cbda created_at 1745510390 with content "kind":1, Happy news! LightningPiggy is heading to -# contacts: event_msg: pubkey: 181137054fe60df5168976311f0bf44dbe4bd4d2e0af69325dfee9fa81a8cbda created_at 1746307620 with content and kind 3 and tags [['p', '181137054fe60df5168976311f0bf44dbe4bd4d2e0af69325dfee9fa81a8cbda'], ['p', 'ffb3f96661bda0295389cfc8c8fe65332e98cc24b12bce5ca40e09af3bb0d7bf'], -# reaction: event_msg: pubkey: 181137054fe60df5168976311f0bf44dbe4bd4d2e0af69325dfee9fa81a8cbda created_at 1746307202 with content + and kind 7 and tags [['e', 'cee2aadc637f56e6f922b95898eecb2bd9b0f0f0ab2e2df6bb6d1e7830c697b0'], ['p', '3e6e0735b8a2e96f8cf663f64d04bb9cea931afcc57f5427c35bb6859e95c8a2']] -# event_msg: pubkey: 181137054fe60df5168976311f0bf44dbe4bd4d2e0af69325dfee9fa81a8cbda created_at 1742146581 with content The kWh (kilowatt-hour) was pro... nd kind 1 and tags [['p', '92cbe5861cfc5213dd89f0a6f6084486f85e6f03cfeb70a13f455938116433b8', 'wss://nostrelites.org', 'mention']] - -# somehow, adding kinds breaks it?! -# ["REQ", "test1747750250", {"since": 1744011312, "kinds": [1], "authors": ["181137054fe60df5168976311f0bf44dbe4bd4d2e0af69325dfee9fa81a8cbda"]}] -# => this gives me EOSE quickly -# ["REQ", "test1747750060", {"since": 1744011312, "authors": ["181137054fe60df5168976311f0bf44dbe4bd4d2e0af69325dfee9fa81a8cbda"]}] -# this worked before, I think: -# ["REQ","index",{"kinds":[9735], "#p": ["181137054fe60df5168976311f0bf44dbe4bd4d2e0af69325dfee9fa81a8cbda"]}] - -import sys -if sys.platform == "esp32": - # on esp32, it needs this correction: - timestamp = time.time() + 946684800 - timetogoback -else: - timestamp = round(time.time()-timetogoback) - #timestamp = round(time.time()-1000) - #timestamp = round(time.time()-5000) - -timestamp = 1744011312 - -filters = Filters([Filter(authors=["181137054fe60df5168976311f0bf44dbe4bd4d2e0af69325dfee9fa81a8cbda"], since=timestamp)]) -#filters = Filters([Filter(authors=["181137054fe60df5168976311f0bf44dbe4bd4d2e0af69325dfee9fa81a8cbda"], since=timestamp, kinds=[EventKind.TEXT_NOTE] )]) -#filters = Filters([Filter(authors=["04c915daefee38317fa734444acee390a8269fe5810b2241e5e6dd343dfbecc9"], kinds=[9735], since=timestamp)]) -#filters = Filters([Filter(kinds=[9735], since=timestamp)]) - -subscription_id = "test" + str(round(time.time())) -request = [ClientMessageType.REQUEST, subscription_id] -json.dumps(request) -request.extend(filters.to_json_array()) -message = json.dumps(request) -# ["REQ", "ihopethisworks3", {"kinds": [1], "authors": "04c915daefee38317fa734444acee390a8269fe5810b2241e5e6dd343dfbecc9"}] -print(f"sending this: {message}") - -def printevents(): - import micropython - print(f"at the start, thread stack used: {micropython.stack_use()}") - print("relaymanager") - relay_manager = RelayManager() - #relay_manager.add_relay("wss://nostr-pub.wellorder.net") - print("relaymanager adding") - relay_manager.add_relay("wss://relay.primal.net") - #relay_manager.add_relay("wss://relay.damus.io") - print("relaymanager subscribing") - relay_manager.add_subscription(subscription_id, filters) - print("opening connections") # after this, CPU usage goes high and stays there - relay_manager.open_connections({"cert_reqs": ssl.CERT_NONE}) # NOTE: This disables ssl certificate verification - time.sleep(2) # allow the connections to open - print("publishing:") - relay_manager.publish_message(message) - time.sleep(2) # allow the messages to send - print("printing events:") - #while relay_manager.message_pool.has_events(): - # allowing 30 seconds for stuff to come in... - for _ in range(600): - time.sleep(1) - print("checking pool....") - try: - event_msg = relay_manager.message_pool.get_event() - print(f"event_msg: pubkey: {event_msg.event.public_key} created_at {event_msg.event.created_at} with content '{event_msg.event.content}' and kind {event_msg.event.kind} and tags {event_msg.event.tags}") - except Exception as e: - #print(f"pool.get_event() got error: {e}") - pass - print("30 seconds passed, closing:") - relay_manager.close_connections() - -# new thread so REPL stays available -# 12KB crashes here: -# opening connections -# [DEBUG 408724546] Starting run_forever -# [DEBUG 408724546] Starting _async_main -# [DEBUG 408724546] Reconnect interval set to 0s -# [DEBUG 408724546] Started callback processing task -# [DEBUG 408724546] Main loop iteration: self.running=True -# [DEBUG 408724546] Connecting to wss://relay.damus.io -# [DEBUG 408724547] Using SSL with no certificate verification -# 24KB is fine -# somehow, if I run this in a thread, I get: can't create thread" at File "/lib/nostr/relay_manager.py", line 48, in open_connections -# tried stack sizes from 18KB up to 32KB -#_thread.stack_size(16*1024) -#_thread.start_new_thread(printevents, ()) -printevents() - - -#import gc -#for _ in range(50): -# collect = gc.collect() -# print(f"MEMFREE: {gc.mem_free()}") -# time.sleep(1) diff --git a/draft_code/nwc-demo.py b/draft_code/nwc-demo.py deleted file mode 100644 index 4b27326f..00000000 --- a/draft_code/nwc-demo.py +++ /dev/null @@ -1,214 +0,0 @@ -import json -import ssl -import time -import sys -from nostr.relay_manager import RelayManager -from nostr.message_type import ClientMessageType -from nostr.filter import Filter, Filters -from nostr.event import EncryptedDirectMessage -from nostr.key import PrivateKey - -def parse_nwc_url(nwc_url): - """Parse Nostr Wallet Connect URL to extract pubkey, relay, secret, and lud16.""" - print(f"DEBUG: Starting to parse NWC URL: {nwc_url}") - try: - # Remove 'nostr+walletconnect://' or 'nwc:' prefix - if nwc_url.startswith('nostr+walletconnect://'): - print(f"DEBUG: Removing 'nostr+walletconnect://' prefix") - nwc_url = nwc_url[22:] - elif nwc_url.startswith('nwc:'): - print(f"DEBUG: Removing 'nwc:' prefix") - nwc_url = nwc_url[4:] - else: - print(f"DEBUG: No recognized prefix found in URL") - raise ValueError("Invalid NWC URL: missing 'nostr+walletconnect://' or 'nwc:' prefix") - - print(f"DEBUG: URL after prefix removal: {nwc_url}") - - # Split into pubkey and query params - parts = nwc_url.split('?') - pubkey = parts[0] - print(f"DEBUG: Extracted pubkey: {pubkey}") - - # Validate pubkey (should be 64 hex characters) - if len(pubkey) != 64 or not all(c in '0123456789abcdef' for c in pubkey): - raise ValueError("Invalid NWC URL: pubkey must be 64 hex characters") - - # Extract relay, secret, and lud16 from query params - relay = None - secret = None - lud16 = None - if len(parts) > 1: - print(f"DEBUG: Query parameters found: {parts[1]}") - params = parts[1].split('&') - for param in params: - if param.startswith('relay='): - relay = param[6:] - print(f"DEBUG: Extracted relay: {relay}") - elif param.startswith('secret='): - secret = param[7:] - print(f"DEBUG: Extracted secret: {secret}") - elif param.startswith('lud16='): - lud16 = param[6:] - print(f"DEBUG: Extracted lud16: {lud16}") - else: - print(f"DEBUG: No query parameters found") - - if not pubkey or not relay or not secret: - raise ValueError("Invalid NWC URL: missing required fields (pubkey, relay, or secret)") - - # Validate secret (should be 64 hex characters) - if len(secret) != 64 or not all(c in '0123456789abcdef' for c in secret): - raise ValueError("Invalid NWC URL: secret must be 64 hex characters") - - return { - 'relay': relay, - 'pubkey': pubkey, - 'secret': secret, - 'lud16': lud16 - } - except Exception as e: - print(f"DEBUG: Error parsing NWC URL: {e}") - sys.exit(1) - -def get_balance(nwc_url): - """Get balance using Nostr Wallet Connect.""" - print(f"DEBUG: Starting get_balance with NWC URL: {nwc_url}") - # Parse NWC URL - nwc_data = parse_nwc_url(nwc_url) - relay = nwc_data['relay'] - wallet_pubkey = nwc_data['pubkey'] - secret = nwc_data['secret'] - lud16 = nwc_data['lud16'] - print(f"DEBUG: Parsed NWC data - Relay: {relay}, Pubkey: {wallet_pubkey}, Secret: {secret}, lud16: {lud16}") - - # Initialize private key from secret (assuming it's a hex key) - try: - #print(f"DEBUG: Initializing private key from secret") - private_key = PrivateKey(bytes.fromhex(secret)) - print(f"DEBUG: Private key initialized, public key: {private_key.public_key.hex()}") - except Exception as e: - print(f"DEBUG: Error initializing private key: {e}") - sys.exit(1) - - # Create get_balance request - balance_request = { - "method": "get_balance", - "params": {} - } - print(f"DEBUG: Created balance request: {balance_request}") - - #balance_request_string = json.dumps(balance_request) - #encrypted = private_key.encrypt_message(balance_request_string, wallet_pubkey) - #print(f"\n\n\nencryption returned: {encrypted}") - #decrypted = private_key.decrypt_message(encrypted, wallet_pubkey) - #print(f"\n\n\ndecryption returned: {decrypted}\n\n\n") - - #decrypted = private_key.decrypt_message(encrypted, wallet_pubkey) - #print(f"\n\n\ndecryption from nak returned: {decrypted}\n\n\n") - # padding error - - - # Create encrypted DM with the balance request - print(f"DEBUG: Creating encrypted DM to wallet pubkey: {wallet_pubkey}") - dm = EncryptedDirectMessage( - recipient_pubkey=wallet_pubkey, - cleartext_content=json.dumps(balance_request) - ) - - - print(f"DEBUG: Signing DM {json.dumps(dm)} with private key") - private_key.sign_event(dm) # sign also does encryption if it's a encrypted dm - print(f"DEBUG: DM created with ID: {dm.id}") - - # Set up relay manager - print(f"DEBUG: Setting up relay manager with relay: {relay}") - relay_manager = RelayManager() - relay_manager.add_relay(relay) - print(f"DEBUG: Opening relay connections") - relay_manager.open_connections({"cert_reqs": ssl.CERT_NONE}) - time.sleep(2) # Allow connections to open - - # Check for relay connection notices - print(f"DEBUG: Checking for relay notices") - while relay_manager.message_pool.has_notices(): - notice = relay_manager.message_pool.get_notice() - print(f"DEBUG: Relay notice: {notice.content}") - - # Set up subscription to receive response - subscription_id = "nwc_balance_" + str(round(time.time())) - #print(f"DEBUG: Setting up subscription with ID: {subscription_id}") - filters = Filters([Filter( - kinds=[23195], # NWC replies - authors=[wallet_pubkey], - pubkey_refs=[private_key.public_key.hex()] - )]) - #print(f"DEBUG: Subscription filters: {filters.to_json_array()}") - relay_manager.add_subscription(subscription_id, filters) - - # Publish request - print(f"DEBUG: Publishing subscription request") - request_message = [ClientMessageType.REQUEST, subscription_id] - request_message.extend(filters.to_json_array()) - relay_manager.publish_message(json.dumps(request_message)) - print(f"DEBUG: Publishing encrypted DM") - relay_manager.publish_event(dm) - # only accept events after the time it was published - after_time = time.time() - if sys.platform == "esp32": - # on esp32, it needs this correction: - after_time += 946684800 - after_time -= 60 # go back a bit because server clocks might be drifting - print(f"will only consider events after {after_time}") - - - # Wait for response - print(f"DEBUG: Waiting for response...") - print(f"starting at {time.localtime()}") - start_time = time.time() - balance = None - while time.time() - start_time < 60 * 2: - while relay_manager.message_pool.has_events(): - print(f"DEBUG: Event received from message pool") - event_msg = relay_manager.message_pool.get_event() - event_created_at = event_msg.event.created_at - print(f"Received at {time.localtime()} a message with timestamp {event_created_at}") - if event_created_at < after_time: - print("Skipping event because it's too old!") - continue - #print(f"event_msg content {event_msg.event.content}") - try: - #print(f"DEBUG: Decrypting event from public_key: {event_msg.event.public_key}") - decrypted_content = private_key.decrypt_message( - event_msg.event.content, - event_msg.event.public_key - ) - print(f"DEBUG: Decrypted content: {decrypted_content}") - response = json.loads(decrypted_content) - print(f"DEBUG: Parsed response: {response}") - if response.get("method") == "get_balance": - balance = response.get("result", {}).get("balance") - print(f"DEBUG: Balance found: {balance} satoshis") - break - except Exception as e: - print(f"DEBUG: Error processing response: {e}") - if balance is not None: - break - time.sleep(1) - - print(f"finished at {time.localtime()}") - - # Close connections - print(f"DEBUG: Closing relay connections") - relay_manager.close_connections() - - if balance is not None: - print(f"Balance: {balance} satoshis") - else: - print("No balance response received or request timed out") - -# Example usage -#nwc_url = "nostr+walletconnect://b889ff5b1513b641e2a139f661a661364979c5beee91842f8f0ef42ab558e9d4?relay=wss%3A%2F%2Frelay.getalby.com/v1&secret=71a8c14c1407c113601079c4302dab36460f0ccd0ad506f1f2dc73b5100e4f3c&lud16=moritz@getalby.com" -#nwc_url = "nostr+walletconnect://b889ff5b1513b641e2a139f661a661364979c5beee91842f8f0ef42ab558e9d4?relay=wss://relay.getalby.com/v1&secret=71a8c14c1407c113601079c4302dab36460f0ccd0ad506f1f2dc73b5100e4f3c&lud16=moritz@getalby.com" -print(f"Processing NWC URL: {nwc_url}") -get_balance(nwc_url) diff --git a/draft_code/qmi8658_reworked.py b/draft_code/qmi8658_reworked.py deleted file mode 100644 index e9e8fae8..00000000 --- a/draft_code/qmi8658_reworked.py +++ /dev/null @@ -1,142 +0,0 @@ -import struct -import time - -from machine import I2C - - -# Sensor constants -_QMI8685_PARTID = const(0x05) -_REG_PARTID = const(0x00) -_REG_REVISION = const(0x01) - -_REG_CTRL1 = const(0x02) # Serial interface and sensor enable -_REG_CTRL2 = const(0x03) # Accelerometer settings -_REG_CTRL3 = const(0x04) # Gyroscope settings -_REG_CTRL4 = const(0x05) # Magnetomer settings (support not implemented in this driver yet) -_REG_CTRL5 = const(0x06) # Sensor data processing settings -_REG_CTRL6 = const(0x07) # Attitude Engine ODR and Motion on Demand -_REG_CTRL7 = const(0x08) # Enable Sensors and Configure Data Reads - -_REG_TEMP = const(0x33) # Temperature sensor. - -_REG_AX_L = const(0x35) # Read accelerometer -_REG_AX_H = const(0x36) -_REG_AY_L = const(0x37) -_REG_AY_H = const(0x38) -_REG_AZ_L = const(0x39) -_REG_AZ_H = const(0x3A) - -_REG_GX_L = const(0x3B) # read gyro -_REG_GX_H = const(0x3C) -_REG_GY_L = const(0x3D) -_REG_GY_H = const(0x3E) -_REG_GZ_L = const(0x3F) -_REG_GZ_H = const(0x40) - -_QMI8658_I2CADDR_DEFAULT = const(0X6B) - - -_ACCELSCALE_RANGE_2G = const(0b00) -_ACCELSCALE_RANGE_4G = const(0b01) -_ACCELSCALE_RANGE_8G = const(0b10) -_ACCELSCALE_RANGE_16G = const(0b11) - -_GYROSCALE_RANGE_16DPS = const(0b000) -_GYROSCALE_RANGE_32DPS = const(0b001) -_GYROSCALE_RANGE_64DPS = const(0b010) -_GYROSCALE_RANGE_128DPS = const(0b011) -_GYROSCALE_RANGE_256DPS = const(0b100) -_GYROSCALE_RANGE_512DPS = const(0b101) -_GYROSCALE_RANGE_1024DPS = const(0b110) -_GYROSCALE_RANGE_2048DPS = const(0b111) - -_ODR_8000HZ = const(0b0000) -_ODR_4000HZ = const(0b0001) -_ODR_2000HZ = const(0b0010) -_ODR_1000HZ = const(0b0011) -_ODR_500HZ = const(0b0100) -_ODR_250HZ = const(0b0101) -_ODR_125HZ = const(0b0110) -_ODR_62_5HZ = const(0b0111) - - -class QMI8658: - global _QMI8658_I2CADDR_DEFAULT - def __init__(self,i2c_bus: I2C,address: int = _QMI8658_I2CADDR_DEFAULT,accel_scale: int = _ACCELSCALE_RANGE_8G,gyro_scale: int = _GYROSCALE_RANGE_256DPS): - self.i2c = i2c_bus - self.address = address - # Verify sensor part ID - if self._read_u8(_REG_PARTID) != _QMI8685_PARTID: - raise AttributeError("Cannot find a QMI8658") - # Setup initial configuration - self._configure_sensor(accel_scale, gyro_scale) - # Configure scales/divisors for the driver - self.acc_scale_divisor = { - _ACCELSCALE_RANGE_2G: 1 << 14, - _ACCELSCALE_RANGE_4G: 1 << 13, - _ACCELSCALE_RANGE_8G: 1 << 12, - _ACCELSCALE_RANGE_16G: 1 << 11, - }[accel_scale] - self.gyro_scale_divisor = { - _GYROSCALE_RANGE_16DPS: 2048, - _GYROSCALE_RANGE_32DPS: 1024, - _GYROSCALE_RANGE_64DPS: 512, - _GYROSCALE_RANGE_128DPS: 256, - _GYROSCALE_RANGE_256DPS: 128, - _GYROSCALE_RANGE_512DPS: 64, - _GYROSCALE_RANGE_1024DPS: 32, - _GYROSCALE_RANGE_2048DPS: 16, - }[gyro_scale] - - - def _configure_sensor(self, accel_scale: int, gyro_scale: int): - # Initialize accelerometer and gyroscope settings - self._write_u8(_REG_CTRL1, 0x60) # Set SPI auto increment and big endian (Ctrl 1) - self._write_u8(_REG_CTRL2, (accel_scale << 4) | _ODR_1000HZ) # Accel Config - self._write_u8(_REG_CTRL3, (gyro_scale << 4) | _ODR_1000HZ) # Gyro Config - self._write_u8(_REG_CTRL5, 0x01) # Low-pass filter enable - self._write_u8(_REG_CTRL7, 0x03) # Enable accel and gyro - time.sleep_ms(100) - - - # Helper functions for register operations - def _read_u8(self, reg:int) -> int: - return self.i2c.readfrom_mem(self.address, reg, 1)[0] - - def _read_xyz(self, reg:int) -> tuple[int, int, int]: - data = self.i2c.readfrom_mem(self.address, reg, 6) - return struct.unpack(' float: - """Get the device temperature.""" - temp_raw = self._read_u8(_REG_TEMP) - return temp_raw / 256 - - @property - def acceleration(self) -> tuple[float, float, float]: - """Get current acceleration reading.""" - raw_accel = self._read_xyz(_REG_AX_L) - return tuple(val / self.acc_scale_divisor for val in raw_accel) - - @property - def gyro(self) -> tuple[float, float, float]: - """Get current gyroscope reading.""" - raw_gyro = self._read_xyz(_REG_GX_L) - return tuple(val / self.gyro_scale_divisor for val in raw_gyro) - - -import machine -sensor = QMI8658(I2C(0, sda=machine.Pin(48), scl=machine.Pin(47))) -while True: - print(f""" -QMI8685 -{sensor.temperature=} -{sensor.acceleration=} -{sensor.gyro=} -""") - time.sleep(1) diff --git a/draft_code/qrdecode.py b/draft_code/qrdecode.py deleted file mode 100644 index 72bfe6f6..00000000 --- a/draft_code/qrdecode.py +++ /dev/null @@ -1,39 +0,0 @@ -import qrdecode -import random - -# Create a 240x240 byte buffer -buffer = bytearray(240 * 240) - -# Fill buffer with random bytes - -# Image dimensions -width = 240 -height = 240 -buffer_size = width * height # 240 * 240 = 57600 bytes -try: - # Allocate buffer for grayscale image - buffer = bytearray(buffer_size) - #for i in range(240 * 240): - # buffer[i] = random.getrandbits(8) - # Read the raw grayscale image file - with open('qrcode2.raw', 'rb') as f: - bytes_read = f.readinto(buffer) - if bytes_read != buffer_size: - raise ValueError("File size does not match expected 240x240 grayscale image") - # Decode QR code using qrdecode module - print("decoding...") - print(f"buffer length: {len(buffer)}") - for i in range(15): - print(buffer[i]) - result = qrdecode.qrdecode(buffer, width, height) - print(f"result: {result}") - # Remove BOM (\ufeff) from the start of the decoded string, if present - #if result.startswith('\ufeff'): - # result = result[1:] - print(f"result: {result}") -except OSError as e: - print("Error reading file:", e) - raise -except ValueError as e: - print("Error:", e) - raise diff --git a/draft_code/queue_test.py b/draft_code/queue_test.py deleted file mode 100644 index 6d0515f2..00000000 --- a/draft_code/queue_test.py +++ /dev/null @@ -1,64 +0,0 @@ -import uasyncio -from collections import deque - -class AsyncQueue: - def __init__(self, maxlen=10): # Set a default maximum length - self._queue = deque((), maxlen, True) # Initialize deque with specified maxlen - self._event = uasyncio.Event() # Event for signaling when items are added - - async def get(self, timeout=None): - """Get an item from the queue, waiting if empty until an item is available or timeout expires.""" - while not self._queue: - if timeout is not None: - try: - await uasyncio.wait_for(self._event.wait(), timeout) # Wait for item or timeout - except uasyncio.TimeoutError: - raise Empty("Queue is empty and timed out") - else: - await self._event.wait() # Wait indefinitely for an item - self._event.clear() # Clear event after waking up - return self._queue.popleft() # Return the item - - async def put(self, item): - """Put an item in the queue and signal waiting coroutines.""" - self._queue.append(item) # This will now work with proper maxlen - self._event.set() # Signal that an item is available - - def qsize(self): - """Return the current size of the queue.""" - return len(self._queue) - - def empty(self): - """Return True if the queue is empty.""" - return len(self._queue) == 0 - -class Empty(Exception): - """Exception raised when queue is empty and non-blocking or timeout occurs.""" - pass - - -import uasyncio -#from async_queue import AsyncQueue, Empty # Assuming the above code is in async_queue.py - -async def producer(queue): - for i in range(5): - print(f"Producing {i}") - await queue.put(i) - await uasyncio.sleep(1) # Simulate some delay - -async def consumer(queue): - while True: - try: - item = await queue.get(timeout=2.0) # Wait up to 2 seconds - print(f"Consumed {item}") - except Empty: - print("Consumer timed out waiting for item") - break - -async def main(): - queue = AsyncQueue() - # Run producer and consumer concurrently in the event loop - await uasyncio.gather(producer(queue), consumer(queue)) - -# Run the event loop -uasyncio.run(main()) diff --git a/draft_code/saved_functions.py b/draft_code/saved_functions.py deleted file mode 100644 index 74ddc65b..00000000 --- a/draft_code/saved_functions.py +++ /dev/null @@ -1,727 +0,0 @@ - - - -import network -import time -wlan = network.WLAN(network.STA_IF) -wlan.active(True) -wlan.connect("SSIDHERE", "PASSWORDHERE") -print("Connecting to Wi-Fi...") -time.sleep(5) -start_app("/apps/com.example.appstore") - - - - -import mip -mip.install('github:echo-lalia/qmi8658-micropython') -# remove multi line comments - -from machine import Pin, I2C -from qmi8658 import QMI8658 -import time -import machine -sensor = QMI8658(I2C(0, sda=machine.Pin(48), scl=machine.Pin(47))) -print(f""" -QMI8685 -{sensor.temperature=} -{sensor.acceleration=} -{sensor.gyro=} -""") - - - -wifi_icon = lv.label(lv.screen_active()) -wifi_icon.set_text("Test label") -wifi_icon.align(lv.ALIGN.CENTER, 0, 0) -wifi_icon.set_style_text_color(lv.color_hex(0x0000FF), 0) - - - - -# This file is executed on every boot (including wake-boot from deepsleep) -#import esp -#esp.osdebug(None) -#import webrepl -#webrepl.start() - - - -# Fetch Bitcoin block height from mempool.space -def get_block_height(): - try: - response = urequests.get("https://mempool.space/api/blocks/tip/height") - if response.status_code == 200: - height = response.text.strip() # Returns plain text (e.g., "853123") - response.close() - return height - else: - response.close() - return "Error: HTTP " + str(response.status_code) - except Exception as e: - return "Error: " + str(e) - -def show_block_height(): - # Create a label for block height - label = lv.label(scr) - label.set_text("Bitcoin Block Height: Fetching...") - label.set_style_text_color(lv.color_make(0, 255, 0), 0) # Green text - label.set_style_text_font(lv.font_montserrat_16, 0) # Larger font (if available) - label.align(lv.ALIGN.TOP_LEFT, 10, 200) - #label.center() - - # Style for label background - style = lv.style_t() - style.init() - style.set_bg_color(lv.palette_main(lv.PALETTE.DARK)) # Dark background - style.set_border_width(2) - style.set_border_color(lv.color_make(255, 255, 255)) # White border - style.set_pad_all(10) - style.set_radius(10) - label.add_style(style, 0) - - height = get_block_height() - label.set_text(f"Block Height: {height}") - - - - - - - -# Create file explorer widget -file_explorer = lv.file_explorer(lv.screen_active()) -#file_explorer.set_root_path("/") -#file_explorer.explorer_open_dir('/') -file_explorer.explorer_open_dir('P:.') # POSIX works, fs_driver doesn't because it doesn't have dir_open, dir_read, dir_close -#file_explorer.explorer_open_dir('S:/') -file_explorer.set_size(210, 210) -#file_explorer.set_mode(lv.FILE_EXPLORER.MODE.DEFAULT) # Default browsing mode -#file_explorer.set_sort(lv.FILE_EXPLORER.SORT.NAME_ASC) # Sort by name, ascending -file_explorer.align(lv.ALIGN.CENTER, 0, 0) -def file_explorer_event_cb(e): - code = e.get_code() - print(f"file_explorer_event_cb {code}") - obj = e.get_target_obj() - if code == lv.EVENT.VALUE_CHANGED: - #selected_path = obj.get_selected_file_name() - selected_path = file_explorer.explorer_get_selected_file_name() - print("Selected:", selected_path) - #if obj.is_selected_dir(): - # print("This is a directory") - #else: - # print("This is a file") - - -# Attach event callback -file_explorer.add_event_cb(file_explorer_event_cb, lv.EVENT.VALUE_CHANGED, None) - - - - - -#show_block_height() - -# Connect to Wi-Fi and fetch block height -#if connect_wifi(): -#else: -# label.set_text("Block Height: Wi-Fi Error") - - -import os -print(os.listdir('/')) -try: - with open('/boot.py', 'r') as file: - print("Contents of /boot.py:") - print("-" * 20) - for line in file: - print(line.rstrip()) # Remove trailing newlines for clean output -except OSError as e: - print("Error reading /boot.py:", e) - -#with open('/block_height.txt', 'w') as f: -# f.write('853123') - - - - - - -# ffmpeg isn't compiled in... -# Create video widget -subwindow.clean() -video = lv.video(subwindow) -video.set_size(320, 200) -video.center() - -# Open and play video using LVGL's FFmpeg backend -video_path = "/video/video_320x180.avi" -video.set_src(f"file://{video_path}") -video.set_play_mode(lv.VIDEO_PLAY_MODE.PLAY) # Start playback -video.play() - - -script_globals = { - 'lv': lv, - #'subwindow': lvgl_obj, -} - -with open("/launcher.py", 'r') as f: - script_source = f.read() - - -exec(script_source, script_globals) - - - - - - - -# Debug file system -image_path = "/test.jpg" -try: - print("Checking file system...") - print(f"Apps dir: {uos.listdir('/apps')}") - print(f"App1 dir: {uos.listdir('/apps/com.example.app1')}") - print(f"Res dir: {uos.listdir('/apps/com.example.app1/res')}") - print(f"Mipmap dir: {uos.listdir('/apps/com.example.app1/res/mipmap-mdpi')}") - print(f"File exists: {image_path in uos.listdir('/apps/com.example.app1/res/mipmap-mdpi')}") -except Exception as e: - print(f"File system error: {e}") - -# Load and display the image -print("Creating image widget...") -image = lv.image(lv.screen_active()) -try: - print(f"Loading image: {image_path}") - image.set_src(image_path) - image.align(lv.ALIGN.CENTER, 0, 0) - print("Image loaded and aligned") -except Exception as e: - print(f"Image load error: {e}") - -# Debug screen and widget -print(f"Screen active: {lv.screen_active()}") -print(f"Image widget: {image}") - - - - - - - -# Debug display -#print(f"Display registered: {lv.disp}") -#print(f"Display resolution: {lv.display_get_horizontal_resolution(lv.disp)}x{lv.display_get_vertical_resolution(lv.disp)}") - -# lv.lodepng_init() not needed - - -# PNG: -with open("/icon_64x64.png", 'rb') as f: - image_data = f.read() -image_dsc = lv.image_dsc_t({ - 'data_size': len(image_data), - 'data': image_data -}) -image1 = lv.image(lv.screen_active()) -image1.set_src(image_dsc) -image1.set_pos(150,100) - - - - -# GIF: -#with open("../icons/spongebob_happy_love_it.gif", 'rb') as f: -with open("../icons/corel-draw-icon-5662.png", 'rb') as f: -with open("../icons/cpu_3dbd2b17ab4c68a4eb7e4034ab7c1c0e.jpg", 'rb') as f: -with open("../icons/pngtree-update-icon-glossy-blue-round-button-symbol-rotate-button-photo-image_18021430.jpg", 'rb') as f: -with open("../icons/hello_world_8844577_64x64.png", 'rb') as f: # one of the only images that works! -with open("../icons/Spinning-Wheel-Vector-PNG-Cutout_64x64.png", 'rb') as f: # this also works... -with open("../icons/pngtree-update-icon-glossy-blue-round-button-symbol-rotate-button-photo-image_18021430_square.png", 'rb') as f: # dontwork - print("loading image...") - image_data = f.read() - image_dsc = lv.image_dsc_t({ - 'data_size': len(image_data), - 'data': image_data - }) - print(f"loaded {len(image_data)} bytes") - screen = lv.screen_active() - screen.clean() - image = lv.image(screen) - image.set_src(image_dsc) - #image1.set_pos(10,10) - #image.set_size(323,404) - image.align(lv.ALIGN.TOP_MID, 0, 0) - print("done") - - -# lv.gd_open_gif_file()) - -#with open("../icons/graphics-snakes-834669.gif", 'rb') as f: # works -with open("../icons/spongebob_happy_love_it.gif", 'rb') as f: # works -with open("../icons/big-buck-bunny_320x180.gif", 'rb') as f: # works - print("loading image...") - image_data = f.read() - image_dsc = lv.image_dsc_t({ - 'data_size': len(image_data), - 'data': image_data - }) - print(f"loaded {len(image_data)} bytes") - screen = lv.screen_active() - screen.clean() - gif = lv.gif(screen) - gif.set_src(image_dsc) - gif.align(lv.ALIGN.TOP_MID, 0, 0) - print("done") - - -screen = lv.obj() -gif = lv.gif(screen) -gif = lv.gif(lv.screen_active()) -gif.set_src("M:data/images/tunnel_160x107.gif") -gif.center() -#gif.set_size(320,240) -lv.screen_load(screen) - -# floating image: -img = lv.image(lv.screen_active()) -img.set_src("M:data/images/icon_64x64.png") -img.set_pos(50,50) -#img.move_foreground() -#img.set_flags(lv.LAYOUT.NONE) -#img.center() - -gif = lv.gif(lv.screen_active()) -gif.set_pos(150,150) -#gif.set_src("M:data/images/tunnel_160x107.gif") -gif.set_src("M:data/images/graphics-snakes-834669.gif") - - - -# BIN -with open("/icon_64x64.bin", 'rb') as f: - image_data = f.read() - -image_dsc = lv.image_dsc_t({ - 'data_size': len(image_data), - 'data': image_data -}) -image1 = lv.image(subwindow) -image1.set_src(image_data) -image1.set_pos(150,100) - - - - -# BIN -with open("/icon_64x64.bin", 'rb') as f: - image_data = f.read() - -image_dsc = lv.image_dsc_t({ - 'data_size': len(image_data), - 'data': image_data -}) -image1 = lv.image(subwindow) -image1.set_src("A:/icon_64x64.bin") -image1.set_pos(150,100) -image1 = lv.image(subwindow) -image1.set_src("/icon_64x64.bin") -image1.set_pos(150,100) - -# WORKING BIN: -import lvgl as lv -import utime - -# Initialize LVGL (assuming already done) -lv.init() - -# Load the binary image data (including 12-byte header) -with open("/icon_64x64.bin", 'rb') as f: - image_data = f.read() - -# Verify the data size (64x64 RGB565 + 12-byte header = 8204 bytes) -if len(image_data) != 8204: - raise ValueError("Invalid image data size") - -# Keep image_data alive to prevent garbage collection -global_image_data = image_data # Store globally to pin in memory - -# Create an lv_image_dsc_t descriptor, letting LVGL parse the header -image_dsc = lv.image_dsc_t({ - "header": { - "magic": lv.IMAGE_HEADER_MAGIC, - "w": 64, - "h": 64, - "stride": 64 * 2, - "cf": lv.COLOR_FORMAT.RGB565 - }, - "data": global_image_data, # Entire 8204 bytes (header + pixel data) - "data_size": len(image_data) # Total size (8204 bytes) -}) - -# Create an image widget -img = lv.image(lv.screen_active()) -img.set_src(image_dsc) # Set the image source to the descriptor -img.center() # Center the image on the screen - - - - - - - - - -try: - print("Checking file system...") - print(f"Apps dir: {uos.listdir('/apps')}") - print(f"App1 dir: {uos.listdir('/apps/com.example.app1')}") - print(f"Res dir: {uos.listdir('/apps/com.example.app1/res')}") - print(f"Mipmap dir: {uos.listdir('/apps/com.example.app1/res/mipmap-mdpi')}") - print(f"File exists: {image_path in uos.listdir('/apps/com.example.app1/res/mipmap-mdpi')}") -except Exception as e: - print(f"File system error: {e}") - -# Create a label to ensure something displays -label = lv.label(lv.screen_active()) -label.set_text("Loading image...") -label.align(lv.ALIGN.TOP_MID, 0, 10) -print("Label created") - -# Load the image - - -# Load and display the image -print("Creating image widget...") -image = lv.image(lv.screen_active()) -try: - print(f"Loading image: {image_path}") - image.set_src(image_path) - image.align(lv.ALIGN.CENTER, 0, 0) - print("Image loaded and aligned") -except Exception as e: - print(f"Image load error: {e}") - print("Falling back to SYMBOL.DUMMY") - image.set_src(lv.SYMBOL.DUMMY) - image.align(lv.ALIGN.CENTER, 0, 0) - -# Debug image properties -print(f"Screen active: {lv.screen_active()}") -print(f"Image widget: {image}") -print(f"Image source: {image.get_src()}") -print(f"Image size: {image.get_width()}x{image.get_height()}") - - - -wifi_icon = lv.label(lv.screen_active()) -wifi_icon.set_text(lv.SYMBOL.WIFI) -wifi_icon.align(lv.ALIGN.RIGHT_CENTER, 0, 0) -wifi_icon.set_style_text_color(COLOR_TEXT_WHITE, 0) - - - - - -# Create a label -label = lv.label(subwindow) -label.set_text("Monospace Text") -label.align(lv.ALIGN.CENTER, 0, -40) - -# Create a style for the label -style = lv.style_t() -style.init() -style.set_text_font(lv.font_montserrat_12) -label.add_style(style, 0) # Apply style to the label - - -# Create a label -label = lv.label(subwindow) -label.set_text("Monospace Text") -label.align(lv.ALIGN.CENTER, 0, -20) - -# Create a style for the label -style = lv.style_t() -style.init() -style.set_text_font(lv.font_montserrat_14) # Default font -label.add_style(style, 0) # Apply style to the label - - - -# Create a label -label = lv.label(subwindow) -label.set_text("Monospace Text") -label.align(lv.ALIGN.CENTER, 0, 0) - -# Create a style for the label -style = lv.style_t() -style.init() -style.set_text_font(lv.font_montserrat_16) -label.add_style(style, 0) # Apply style to the label - - -# Create a label -label = lv.label(subwindow) -label.set_text("Monospace Text") -label.align(lv.ALIGN.CENTER, 0, 40) - -# Create a style for the label -style = lv.style_t() -style.init() -style.set_text_font(lv.font_unscii_8) # Set monospace font -label.add_style(style, 0) # Apply style to the label - -# Create a label -label = lv.label(subwindow) -label.set_text("Monospace Text") -label.align(lv.ALIGN.CENTER, 0, 60) - -# Create a style for the label -style = lv.style_t() -style.init() -style.set_text_font(lv.font_unscii_16) # Set monospace font -label.add_style(style, 0) # Apply style to the label - - - - - -# delete folder: -import mip -mip.install("shutil") -import shutil -shutil.rmtree('/apps/com.example.files') - - - -import vfs -vfs.umount('/') -vfs.VfsLfs2.mkfs(bdev) -vfs.mount(bdev, '/') - - - -def memoryview_to_hex_spaced(mv: memoryview) -> str: - """Convert the first 50 bytes of a memoryview to a spaced hex string.""" - sliced = mv[:50] - return ' '.join('{:02x}'.format(b & 0xFF) for b in sliced) - - - - - - - - - - - - - - - - -subwindow.clean() -canary = lv.obj(subwindow) -canary.add_flag(lv.obj.FLAG.HIDDEN) - -subwindow.set_style_bg_color(lv.color_black(), 0) - -label = lv.label(subwindow) -label.set_text("Hello \uf0ac") # Unicode for a symbol (e.g., globe) -label.align(lv.ALIGN.CENTER, 0, 0) - -label2 = lv.label(subwindow) -label2.set_text("Hello " + lv.SYMBOL.DOWNLOAD) -label2.align(lv.ALIGN.CENTER, 0, 25) - - -label2 = lv.label(subwindow) -label2.set_text("Hello " + lv.SYMBOL.DUMMY) -label2.align(lv.ALIGN.CENTER, 0, 50) - - -image = lv.image(subwindow) -image.align(lv.ALIGN.CENTER, 0, -50) -image.set_src(lv.SYMBOL.STOP) # Or use a default image - - - - - ->>> import ota.update ->>> ota.update.from_file("https://demo.lnpiggy.com/static/firmware/ESP32_GENERIC_S3-SPIRAM_OCT_micropython.bin") - - -temp_zip_path = "/apps/temp.zip" -print('\nReading file') -with ZipFile(temp_zip_path) as myzip: - with myzip.open('com.example.files/META-INF/MANIFEST.MF') as myfile: - print(myfile.read()) - - - -import os -try: - import zipfile -except ImportError: - zipfile = None - - -temp_zip_path = "/apps/temp.zip" -print('\nReading file') -with zipfile.ZipFile(temp_zip_path) as myzip: - with myzip.open('com.example.files/assets/files.py') as myfile: - print(myfile.read()) - - -import os -try: - import zipfile -except ImportError: - zipfile = None - -temp_zip_path = "/apps/temp.zip" -print(f"Stat says: {os.stat(temp_zip_path)}") -with zipfile.ZipFile(temp_zip_path, "r") as zip_ref: - print("extracting...") - zip_ref.extractall("/apps") - - - - - - - - - - - -subwindow = lv.obj(newscreen) -subwindow.set_size(TFT_HOR_RES, TFT_VER_RES - NOTIFICATION_BAR_HEIGHT) -subwindow.set_pos(0, NOTIFICATION_BAR_HEIGHT) -subwindow.set_style_border_width(0, 0) -subwindow.set_style_pad_all(0, 0) -lv.screen_load(newscreen) -script_globals = { - 'lv': lv, - 'appscreen': newscreen, - 'subwindow': subwindow, - 'start_app': start_app, # for launcher apps - 'parse_manifest': parse_manifest, # for launcher apps - '__name__': "__main__" -} - - - -import lvgl as lv - -# Buffer to store FPS -fps_buffer = [0] - -# Custom log callback to capture FPS -def log_callback(level, log_str): - global fps_buffer - # Convert log_str to string if it's a bytes object - log_str = log_str.decode() if isinstance(log_str, bytes) else log_str - # Optional: Print for debugging - print(f"Level: {level}, Log: {log_str}") - # Log message format: "sysmon: 25 FPS (refr_cnt: 8 | redraw_cnt: 1), ..." - if "sysmon:" in log_str and "FPS" in log_str: - try: - # Extract FPS value (e.g., "25" from "sysmon: 25 FPS ...") - fps_part = log_str.split("FPS")[0].split("sysmon:")[1].strip() - fps = int(fps_part) - fps_buffer[0] = fps - except (IndexError, ValueError): - pass - -# Register log callback -lv.log_register_print_cb(log_callback) - - -lv.log_register_print_cb(None) - -# Function to get FPS -def get_fps(): - return fps_buffer[0] - - -#fps = get_fps() -#if fps > 0: # Only print when FPS is updated -# print("Current FPS:", fps) - - -# Main loop -def print_fps(): - for _ in range(100): - import time - fps = get_fps() - if fps > 0: # Only print when FPS is updated - print("Current FPS:", fps) - time.sleep(1) - - -import _thread -_thread.stack_size(12*1024) -_thread.start_new_thread(print_fps, ()) - -# crash: - -label = lv.label(lv.screen_active()) -label.delete() -gc.collect() -label.set_text("Crash!") # This will crash -label.set_text(None) -label.set_size(100000, 1000000) - -buf = lv.draw_buf_create(10, 10, lv.COLOR_FORMAT.RGB565, 1) -buf.data[1000000] = 0xFF # Write way beyond buffer size - -# this works to crash it: -from machine import mem32 -mem32[0] = 0xDEADBEEF - - - -# testing stack size: recursion depth * 256 -#normally I get ~16KB - -import _thread -_thread.stack_size(0) - - - -import fs_driver -fs_drv = lv.fs_drv_t() -fs_driver.fs_register(fs_drv, 'M') - -img = lv.image(lv.screen_active()) -#img.set_src("P:/data/images/icon_64x64.jpg") -img.set_src("P:../artwork/icon_64x64.jpg") - - - -group = sdlkeyboard.get_group() -#group.remove_all_objs() -group = lv.group_create() -#group.set_default() - -group = lv.group_get_default() -group.get_focused() - -group.remove_all_objs() - -screen = lv.obj() -lv.screen_load(screen) - -ta1 = lv.textarea(screen) -ta1.align(lv.ALIGN.TOP_MID,0,0) -#group.add_obj(ta1) - -b = lv.button(screen) -b.center() - -import task_handler -task_handler.TaskHandler(duration=5) # 5ms is recommended for MicroPython+LVGL on desktop diff --git a/draft_code/saved_uasyncio_demo.py b/draft_code/saved_uasyncio_demo.py deleted file mode 100644 index 8c9f2706..00000000 --- a/draft_code/saved_uasyncio_demo.py +++ /dev/null @@ -1,133 +0,0 @@ -import lvgl as lv -import uasyncio as asyncio -import utime -import gc - -# Create a subwindow for the child script (half the 320x240 display) -screen = lv.screen_active() -subwindow = lv.obj(screen) -subwindow.set_size(160, 240) # Half width, full height -subwindow.align(lv.ALIGN.LEFT_MID, 0, 0) # Left side -subwindow.set_style_bg_color(lv.color_hex(0xDDDDDD), lv.PART.MAIN) - -# Create a label for parent updates -parent_label = lv.label(screen) -parent_label.set_text("Parent: 0") -parent_label.set_style_text_font(lv.font_montserrat_12, 0) -parent_label.align(lv.ALIGN.TOP_RIGHT, -10, 10) - -# Create a parent button -parent_button = lv.button(screen) -parent_button.set_size(80, 40) -parent_button.align(lv.ALIGN.BOTTOM_RIGHT, -10, -50) -parent_button_label = lv.label(parent_button) -parent_button_label.set_text("Parent Btn") -parent_button_label.set_style_text_font(lv.font_montserrat_12, 0) - -# Create a parent slider -parent_slider = lv.slider(screen) -parent_slider.set_size(100, 10) -parent_slider.set_range(0, 100) -parent_slider.align(lv.ALIGN.BOTTOM_RIGHT, -10, -10) - -# Parent button callback -def parent_button_cb(e): - print("Parent button clicked") - -parent_button.add_event_cb(parent_button_cb, lv.EVENT.CLICKED, None) - -# Parent slider callback -def parent_slider_cb(e): - value = parent_slider.get_value() - print("Parent slider value:", value) - -parent_slider.add_event_cb(parent_slider_cb, lv.EVENT.VALUE_CHANGED, None) - -# Function to execute the child script as a coroutine -async def execute_script(script_source, lvgl_obj): - try: - script_globals = { - 'lv': lv, - 'subwindow': lvgl_obj, - 'asyncio': asyncio, - 'utime': utime - } - print("Child script: Compiling") - code = compile(script_source, "", "exec") - exec(code, script_globals) - update_child = script_globals.get('update_child') - if update_child: - print("Child script: Starting update_child") - await update_child() - else: - print("Child script error: No update_child function defined") - except Exception as e: - print("Child script error:", e) - -# Child script buffer: updates label, adds button and slider -script_buffer = """ -import asyncio -async def update_child(): - print("Child coroutine: Creating UI") - # Label - label = lv.label(subwindow) - label.set_text("Child: 0") - label.set_style_text_font(lv.font_montserrat_12, 0) - label.align(lv.ALIGN.TOP_MID, 0, 10) - # Button - button = lv.button(subwindow) - button.set_size(80, 40) - button.align(lv.ALIGN.BOTTOM_MID, 0, -50) - button_label = lv.label(button) - button_label.set_text("Child Btn") - button_label.set_style_text_font(lv.font_montserrat_12, 0) - # Slider - slider = lv.slider(subwindow) - slider.set_size(100, 10) - slider.set_range(0, 100) - slider.align(lv.ALIGN.BOTTOM_MID, 0, -10) - # Button callback - def button_cb(e): - print("Child button clicked") - button.add_event_cb(button_cb, lv.EVENT.CLICKED, None) - # Slider callback - def slider_cb(e): - value = slider.get_value() - print("Child slider value:", value) - slider.add_event_cb(slider_cb, lv.EVENT.VALUE_CHANGED, None) - # Update loop - count = 0 - while True: - count += 1 - print("Child coroutine: Updating label to", count) - label.set_text(f"Child: {count}") - await asyncio.sleep_ms(2000) # Update every 2s -""" - -# Parent coroutine: updates parent label every 1 second -async def update_parent(): - count = 0 - while True: - count += 1 - print("Parent coroutine: Updating label to", count) - parent_label.set_text(f"Parent: {count}") - gc.collect() - print("Parent coroutine: Free memory:", gc.mem_free()) - await asyncio.sleep_ms(1000) # Update every 1s - -# Main async function to run all tasks -async def main(): - print("Main: Starting tasks") - asyncio.create_task(update_parent()) - asyncio.create_task(execute_script(script_buffer, subwindow)) - while True: - await asyncio.sleep_ms(100) - -# Run the event loop -gc.collect() -print("Free memory before loop:", gc.mem_free()) -try: - asyncio.run(main()) -except Exception as e: - print("Main error:", e) - diff --git a/draft_code/screen_capture.py b/draft_code/screen_capture.py deleted file mode 100644 index abac2afa..00000000 --- a/draft_code/screen_capture.py +++ /dev/null @@ -1,80 +0,0 @@ -import ustruct -import os -#os.mkdir("/flash") - -import lvgl as lv -import micropython -import ustruct - -# Capture the screen to a buffer -snapshot_buf = lv.snapshot_take(lv.screen_active(), lv.COLOR_FORMAT.NATIVE) -if snapshot_buf is None: - print("Failed to capture snapshot") -else: - print("Snapshot captured successfully") - -# Assuming snapshot_buf is from lv.snapshot_take(scr, lv.COLOR_FORMAT.NATIVE) -if snapshot_buf: - # Verify metadata - print("Width:", snapshot_buf.header.w) # Should be 320 - print("Height:", snapshot_buf.header.h) # Should be 240 - print("Data size:", snapshot_buf.data_size) # Should be 153600 - # Get the raw buffer pointer - data_ptr = snapshot_buf.data - data_size = snapshot_buf.data_size - # Use memoryview to access the full buffer - try: - # Create a memoryview of the C buffer - buffer = memoryview(data_ptr)[:data_size] - print("Buffer length:", len(buffer)) # Should be 153600 - # Save to flash storage - with open("/flash/snapshot.bin", "wb") as f: - f.write(buffer) - print("Snapshot saved to /flash/snapshot.bin") - except Exception as e: - print("Error accessing or saving buffer:", e) - # Free the snapshot to avoid memory leaks - lv.snapshot_free(snapshot_buf) -else: - print("Snapshot capture failed") - - - - - -# Assuming snapshot_buf is the lv_img_dsc_t from lv.snapshot_take -if snapshot_buf: - # Get image data and metadata - img_data = snapshot_buf.data # Raw buffer (bytearray) - img_width = snapshot_buf.header.w - img_height = snapshot_buf.header.h - img_data_size = snapshot_buf.data_size - # Save to flash storage - try: - with open("/flash/snapshot.bin", "wb") as f: - f.write(img_data, img_data_size) - print("Snapshot saved to /flash/snapshot.bin") - except OSError as e: - print("Failed to save snapshot:", e) -else: - print("No snapshot to save") - - - - - -if False: - img_data = snapshot_buf.data - img_width = snapshot_buf.header.w - img_height = snapshot_buf.header.h - img_data_size = snapshot_buf.data_size - color_format = lv.COLOR_FORMAT.NATIVE # Store format for reference - try: - with open("/flash/snapshot.bin", "wb") as f: - # Write header: width (4 bytes), height (4 bytes), format (4 bytes) - f.write(ustruct.pack("III", img_width, img_height, color_format)) - # Write image data - f.write(img_data, img_data_size) - print("Snapshot with header saved to /flash/snapshot.bin") - except OSError as e: - print("Failed to save snapshot:", e) diff --git a/draft_code/sdl2_demo.py b/draft_code/sdl2_demo.py deleted file mode 100644 index 8514ac75..00000000 --- a/draft_code/sdl2_demo.py +++ /dev/null @@ -1,79 +0,0 @@ -import sdl2 -import sdl2.ext -import sdl2.sdlttf -import ctypes # Added missing import - -# Initialize SDL2 and TTF -sdl2.ext.init() -sdl2.sdlttf.TTF_Init() - -# Create window and renderer -window = sdl2.ext.Window("Test", size=(800, 600)) -window.show() -renderer = sdl2.ext.Renderer(window) - -# Load font -font = sdl2.sdlttf.TTF_OpenFont(b"/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf", 24) -if not font: - print("Failed to load font!") - exit(1) - -# Initialize text variables -last_key = "No key pressed" -text_surface = None -text_texture = None -fullscreen = False # Track fullscreen state - -def render_text(text): - global text_surface, text_texture - # Clean up previous texture - if text_texture: - sdl2.SDL_DestroyTexture(text_texture) - - # Create new surface and texture - color = sdl2.SDL_Color(r=255, g=255, b=255) - text_surface = sdl2.sdlttf.TTF_RenderText_Solid(font, text.encode('utf-8'), color) - text_texture = sdl2.SDL_CreateTextureFromSurface(renderer.sdlrenderer, text_surface) - -running = True -while running: - events = sdl2.ext.get_events() - for event in events: - if event.type == sdl2.SDL_QUIT: - running = False - elif event.type == sdl2.SDL_KEYDOWN: - key_name = sdl2.SDL_GetKeyName(event.key.keysym.sym).decode() - if key_name == "F": # Toggle fullscreen on 'F' key - fullscreen = not fullscreen - if fullscreen: - sdl2.SDL_SetWindowFullscreen(window.window, sdl2.SDL_WINDOW_FULLSCREEN) - sdl2.SDL_SetWindowSize(window.window, 800, 600) - else: - sdl2.SDL_SetWindowFullscreen(window.window, 0) - sdl2.SDL_SetWindowSize(window.window, 800, 600) - last_key = "Toggled fullscreen" - else: - last_key = f"Key pressed: {key_name}" - render_text(last_key) - - # Clear screen - renderer.clear() - - # Render text if available - if text_texture: - w, h = ctypes.c_int(), ctypes.c_int() - sdl2.SDL_QueryTexture(text_texture, None, None, ctypes.byref(w), ctypes.byref(h)) - dstrect = sdl2.SDL_Rect(x=10, y=10, w=w.value, h=h.value) - sdl2.SDL_RenderCopy(renderer.sdlrenderer, text_texture, None, dstrect) - - # Update display - renderer.present() - -# Cleanup -if text_texture: - sdl2.SDL_DestroyTexture(text_texture) -if text_surface: - sdl2.SDL_FreeSurface(text_surface) -sdl2.sdlttf.TTF_CloseFont(font) -sdl2.sdlttf.TTF_Quit() -sdl2.ext.quit() diff --git a/draft_code/secp256k1_tests.py b/draft_code/secp256k1_tests.py deleted file mode 100644 index 6b961da4..00000000 --- a/draft_code/secp256k1_tests.py +++ /dev/null @@ -1,51 +0,0 @@ -import secp256k1_embedded -import hashlib -from binascii import hexlify - -def secp256k1_example(): - """Usage example for secp256k1 usermodule""" - - # randomize context from time to time - # - it helps against sidechannel attacks - # secp256k1.context_randomize(os.urandom(32)) - - # some random secret key - secret = hashlib.sha256(b"secret key").digest() - - print("Secret key:", hexlify(secret).decode()) - - # Makes sense to check if secret key is valid. - # It will be ok in most cases, only if secret > N it will be invalid - if not secp256k1.ec_seckey_verify(secret): - raise ValueError("Secret key is invalid") - - # computing corresponding pubkey - pubkey = secp256k1.ec_pubkey_create(secret) - - # serialize the pubkey in compressed format - sec = secp256k1.ec_pubkey_serialize(pubkey, secp256k1.EC_COMPRESSED) - print("Public key:", hexlify(sec).decode()) - - # this is how you parse the pubkey - pubkey = secp256k1.ec_pubkey_parse(sec) - - # Signature generation: - - # hash of the string "hello" - msg = hashlib.sha256(b"hello").digest() - # signing - sig = secp256k1.ecdsa_sign(msg, secret) - - # serialization - der = secp256k1.ecdsa_signature_serialize_der(sig) - - print("Signature:", hexlify(der).decode()) - - # verification - if secp256k1.ecdsa_verify(sig, msg, pubkey): - print("Signature is valid") - else: - printf("Invalid signature") - -if __name__ == '__main__': - secp256k1_example() diff --git a/draft_code/simple_thread.py b/draft_code/simple_thread.py deleted file mode 100644 index ab6c8960..00000000 --- a/draft_code/simple_thread.py +++ /dev/null @@ -1,77 +0,0 @@ -import _thread - -# Function to execute the child script as a coroutine -def execute_script(script_source, lvgl_obj): - try: - script_globals = { - 'lv': lv, - 'subwindow': lvgl_obj, - } - print("Child script: Compiling") - code = compile(script_source, "", "exec") - exec(code, script_globals) - app_main = script_globals.get('app_main') - if app_main: - print("Child script: Starting app_main") - app_main() - print("Script finished!") - else: - print("Child script error: No app_main function defined") - except Exception as e: - print("Child script error:", e) - - -# Child script buffer: updates label, adds button and slider -script_buffer = """ -import time -def app_main(): - print("Child coroutine: Creating UI") - # Label - label = lv.label(subwindow) - label.set_text("Child: 0") - label.set_style_text_font(lv.font_montserrat_12, 0) - label.align(lv.ALIGN.TOP_MID, 0, 10) - # Button - button = lv.button(subwindow) - button.set_size(80, 40) - button.align(lv.ALIGN.CENTER, 0, 0) - button_label = lv.label(button) - button_label.set_text("Quit") - button_label.set_style_text_font(lv.font_montserrat_12, 0) - # Slider - slider = lv.slider(subwindow) - slider.set_range(0, 100) - slider.align(lv.ALIGN.BOTTOM_MID, 0, -30) - # Quit flag - should_continue = True - # Button callback - def button_cb(e): - nonlocal should_continue - print("Quit button clicked, exiting child") - should_continue = False - button.add_event_cb(button_cb, lv.EVENT.CLICKED, None) - # Slider callback - def slider_cb(e): - value = slider.get_value() - print("Child slider value:", value) - slider.add_event_cb(slider_cb, lv.EVENT.VALUE_CHANGED, None) - # Update loop - count = 0 - while should_continue: - count += 1 - print("Child coroutine: Updating label to", count) - label.set_text(f"Child: {count}") - time.sleep_ms(1000) - print("Child coroutine: Exiting") -""" - - -# Start the event loop in a background thread -gc.collect() -print("Free memory before loop:", gc.mem_free()) -try: - _thread.stack_size(8192) - _thread.start_new_thread(execute_script, (script_buffer, subwindow)) - print("Event loop started in background thread") -except Exception as e: - print("Error starting event loop thread:", e) diff --git a/draft_code/test_aes_cbc.py b/draft_code/test_aes_cbc.py deleted file mode 100644 index 05307e24..00000000 --- a/draft_code/test_aes_cbc.py +++ /dev/null @@ -1,25 +0,0 @@ -import ucryptolib -import os - -key = os.urandom(32) -iv = bytes.fromhex("cafc34a94307c35f8c8f736831713467") -#iv = bytes.fromhex("cafc34a94307c35f8c8f736831713468") # changing the IV doesn't change the output! -#iv = os.urandom(16) -data = b'{"method":"get_balance","params":{}}' -pad_length = 16 - (len(data) % 16) -padded_data = data + bytes([pad_length] * pad_length) -print(f"Test padded_data: {padded_data.hex()}") - -cipher = ucryptolib.aes(key, 1, iv) -ciphertext = cipher.encrypt(padded_data) -print(f"Test ciphertext: {ciphertext.hex()}") - -cipher = ucryptolib.aes(key, 1, iv) -decrypted = cipher.decrypt(ciphertext) -print(f"Test decrypted: {decrypted.hex()}") - -pad_length = decrypted[-1] -if decrypted[-pad_length:] != bytes([pad_length] * pad_length): - print(f"Test failed: invalid padding, got {decrypted[-pad_length:].hex()}") -else: - print(f"Test passed: valid padding") diff --git a/draft_code/test_aes_cbc_iv.py b/draft_code/test_aes_cbc_iv.py deleted file mode 100644 index aec4403e..00000000 --- a/draft_code/test_aes_cbc_iv.py +++ /dev/null @@ -1,46 +0,0 @@ -import ucryptolib -import os -import sys - -print(f"MicroPython version: {sys.version}") -print(f"Platform: {sys.platform}") - -key = os.urandom(32) -iv1 = bytes.fromhex("cafc34a94307c35f8c8f736831713467") -iv2 = bytes.fromhex("cafc34a94307c35f8c8f736831713468") -iv3 = os.urandom(16) # Random IV -data = b'{"method":"get_balance","params":{}}' -pad_length = 16 - (len(data) % 16) -padded_data = data + bytes([pad_length] * pad_length) -print(f"Test key: {key.hex()}") -print(f"Test padded_data: {padded_data.hex()} (length: {len(padded_data)})") - -mode_cbc = 2 - -# Test with IV1 -cipher1 = ucryptolib.aes(key, mode_cbc, iv1) -ciphertext1 = cipher1.encrypt(padded_data) -print(f"IV1: {iv1.hex()}, Ciphertext1: {ciphertext1.hex()}") - -# Test with IV2 -cipher2 = ucryptolib.aes(key, mode_cbc, iv2) -ciphertext2 = cipher2.encrypt(padded_data) -print(f"IV2: {iv2.hex()}, Ciphertext2: {ciphertext2.hex()}") - -# Test with IV3 -cipher3 = ucryptolib.aes(key, mode_cbc, iv3) -ciphertext3 = cipher3.encrypt(padded_data) -print(f"IV3: {iv3.hex()}, Ciphertext3: {ciphertext3.hex()}") - -# Compare ciphertexts -print(f"Ciphertext1 == Ciphertext2: {ciphertext1 == ciphertext2}") -print(f"Ciphertext1 == Ciphertext3: {ciphertext1 == ciphertext3}") - -# Verify decryption -cipher_decrypt = ucryptolib.aes(key, 1, iv1) -decrypted = cipher_decrypt.decrypt(ciphertext1) -print(f"Decrypted with IV1: {decrypted.hex()}") -if decrypted[-pad_length:] != bytes([pad_length] * pad_length): - print(f"Test failed: invalid padding, got {decrypted[-pad_length:].hex()}") -else: - print(f"Test passed: valid padding") diff --git a/draft_code/timers.py b/draft_code/timers.py deleted file mode 100644 index d8ee2225..00000000 --- a/draft_code/timers.py +++ /dev/null @@ -1,11 +0,0 @@ -from machine import Timer - -# Callback function to be executed periodically -def timer_callback(timer): - print("Timer 500 triggered!") - -# Initialize a timer -timer = Timer(500) # Must be 0-20 on unix/desktop - -# Set up a periodic timer (e.g., trigger every 1000ms) -timer.init(period=1000, mode=Timer.PERIODIC, callback=timer_callback) diff --git a/draft_code/video_player/README.md b/draft_code/video_player/README.md deleted file mode 100644 index d9a12061..00000000 --- a/draft_code/video_player/README.md +++ /dev/null @@ -1,2 +0,0 @@ -This doesn't work because the build with ffmpeg in it fails, -because it needs that STDIO MEM allocator in lib/lv_conf.h and that has a compilation issue. diff --git a/draft_code/video_player/convert_video.sh b/draft_code/video_player/convert_video.sh deleted file mode 100755 index 324594a2..00000000 --- a/draft_code/video_player/convert_video.sh +++ /dev/null @@ -1,3 +0,0 @@ -# https://sample-videos.com/ - -ffmpeg -i SampleVideo_640x360_1mb.mp4 -c:v mjpeg -q:v 7 -vf "fps=15,scale=320:180:flags=lanczos" -c:a pcm_u8 video_320x180.avi diff --git a/draft_code/video_player/player.py b/draft_code/video_player/player.py deleted file mode 100644 index e920fded..00000000 --- a/draft_code/video_player/player.py +++ /dev/null @@ -1,5 +0,0 @@ -p = lv.ffmpeg_player(lv.screen_active()) -p.player_set_src("../artwork/Big_Buck_Bunny_extract.ogv") -p.player_set_auto_restart(True) -p.player_set_cmd(p.PLAYER_CMD.START) -p.center() diff --git a/draft_code/webcam_snippets.py b/draft_code/webcam_snippets.py deleted file mode 100644 index d1e1c560..00000000 --- a/draft_code/webcam_snippets.py +++ /dev/null @@ -1,77 +0,0 @@ -try: - from camera import Camera, GrabMode, PixelFormat, FrameSize, GainCeiling - cam = Camera( - data_pins=[12,13,15,11,14,10,7,2], - vsync_pin=6, - href_pin=4, - sda_pin=21, - scl_pin=16, - pclk_pin=9, - xclk_pin=8, - xclk_freq=20000000, - powerdown_pin=-1, - reset_pin=-1, - #pixel_format=PixelFormat.RGB565, - pixel_format=PixelFormat.GRAYSCALE, - frame_size=FrameSize.R240X240, - grab_mode=GrabMode.LATEST - ) - print("it worked!") -except Exception as e: - print(f"Exception: {e}") - - - -images=300 - -import webcam -import time - - -class Webcam: - def __init__(self): - # webcam.init() returns (obj, capture_grayscale, deinit) - self.obj, self._capture_grayscale, self._deinit = webcam.init() - def capture_grayscale(self): - return self._capture_grayscale(self.obj) - def deinit(self): - return self._deinit(self.obj) - -starttime = time.ticks_ms() - -# Usage -cam = Webcam() -for _ in range(images): - buf = cam.capture_grayscale() - print(len(buf)) # Should print 57600 (240 * 240) - -endtime = time.ticks_ms() - -print(f"duration: {endtime-starttime}ms") - - -cam.deinit() - - - - - - - - - - - - - - -#from webcam import Webcam, init, capture_frame, deinit -import webcam - -cam = webcam.init("/dev/video0") # Initialize webcam with device path -for i in range(1000): - buf = webcam.capture_frame(cam) # Captures frame, returns 240x240 grayscale buffer - print(f"buffer {i} has length {len(buf)}") # Prints 57600 -webcam.deinit(cam) # Deinitializes webcam - - diff --git a/draft_code/websocket_nostr_receive.py b/draft_code/websocket_nostr_receive.py deleted file mode 100644 index 5eaa50f9..00000000 --- a/draft_code/websocket_nostr_receive.py +++ /dev/null @@ -1,97 +0,0 @@ -import json -import ssl -import time -import _thread - -from nostr.filter import Filter, Filters -from nostr.event import Event, EventKind -from nostr.relay_manager import RelayManager -from nostr.message_type import ClientMessageType - -#filters = Filters([Filter(authors=[], kinds=[EventKind.TEXT_NOTE])]) -#filters = Filters([Filter(authors="04c915daefee38317fa734444acee390a8269fe5810b2241e5e6dd343dfbecc9", kinds=[EventKind.TEXT_NOTE])]) -#timestamp = round(time.time()-50) -#timestamp = round(time.time()) # going for zero events to check memory use - -timetogoback = 100 - -import sys -if sys.platform == "esp32": - # on esp32, it needs this correction: - timestamp = time.time() + 946684800 - timetogoback -else: - timestamp = round(time.time()-timetogoback) - #timestamp = round(time.time()-1000) - #timestamp = round(time.time()-5000) - -#filters = Filters([Filter(authors="04c915daefee38317fa734444acee390a8269fe5810b2241e5e6dd343dfbecc9", kinds=[9735], since=timestamp)]) -filters = Filters([Filter(kinds=[9735], since=timestamp)]) - -subscription_id = "test" + str(round(time.time())) -request = [ClientMessageType.REQUEST, subscription_id] -json.dumps(request) -request.extend(filters.to_json_array()) -message = json.dumps(request) -# ["REQ", "ihopethisworks3", {"kinds": [1], "authors": "04c915daefee38317fa734444acee390a8269fe5810b2241e5e6dd343dfbecc9"}] -print(f"sending this: {message}") - -def printevents(): - import micropython - print(f"at the start, thread stack used: {micropython.stack_use()}") - print("relaymanager") - relay_manager = RelayManager() - #relay_manager.add_relay("wss://nostr-pub.wellorder.net") - print("relaymanager adding") - #relay_manager.add_relay("wss://relay.damus.io") - #time.sleep(1) - relay_manager.add_relay("wss://relay.primal.net") - time.sleep(1) - print("relaymanager subscribing") - relay_manager.add_subscription(subscription_id, filters) - time.sleep(1) - print("opening connections") # after this, CPU usage goes high and stays there - relay_manager.open_connections({"cert_reqs": ssl.CERT_NONE}) # NOTE: This disables ssl certificate verification - time.sleep(2) # allow the connections to open - print("publishing:") - relay_manager.publish_message(message) - time.sleep(2) # allow the messages to send - print("printing events:") - #while relay_manager.message_pool.has_events(): - # allowing 30 seconds for stuff to come in... - for _ in range(30): - time.sleep(1) - print("checking pool....") - try: - event_msg = relay_manager.message_pool.get_event() - #print(f"main code got event_msg: pubkey: {event_msg.event.public_key} created_at {event_msg.event.created_at}") - print(f"main code got event_msg: pubkey: {event_msg.event.public_key} created_at {event_msg.event.created_at} with content '{event_msg.event.content}' and kind {event_msg.event.kind} and tags {event_msg.event.tags}") - except Exception as e: - #print(f"pool.get_event() got error: {e}") - pass - print("30 seconds passed, closing:") - relay_manager.close_connections() - -# new thread so REPL stays available -# 12KB crashes here: -# opening connections -# [DEBUG 408724546] Starting run_forever -# [DEBUG 408724546] Starting _async_main -# [DEBUG 408724546] Reconnect interval set to 0s -# [DEBUG 408724546] Started callback processing task -# [DEBUG 408724546] Main loop iteration: self.running=True -# [DEBUG 408724546] Connecting to wss://relay.damus.io -# [DEBUG 408724547] Using SSL with no certificate verification -# 24KB is fine -# somehow, if I run this in a thread, I get: can't create thread" at File "/lib/nostr/relay_manager.py", line 48, in open_connections -# tried stack sizes from 18KB up to 32KB -# on unix/desktop, 24KB crashes, 26KB is fine -_thread.stack_size(16*1024) -_thread.start_new_thread(printevents, ()) -#printevents() - - -#import gc -#for _ in range(50): -# collect = gc.collect() -# print(f"MEMFREE: {gc.mem_free()}") -# time.sleep(1) diff --git a/draft_code/websocket_nostr_test.py b/draft_code/websocket_nostr_test.py deleted file mode 100644 index 3b473914..00000000 --- a/draft_code/websocket_nostr_test.py +++ /dev/null @@ -1,23 +0,0 @@ -import json -import ssl -import time -from nostr.event import Event -from nostr.relay_manager import RelayManager -from nostr.message_type import ClientMessageType -from nostr.key import PrivateKey - -relay_manager = RelayManager() -relay_manager.add_relay("wss://nostr-pub.wellorder.net") -relay_manager.add_relay("wss://relay.damus.io") -relay_manager.open_connections({"cert_reqs": ssl.CERT_NONE}) # NOTE: This disables ssl certificate verification -time.sleep(5) # allow the connections to open - -private_key = PrivateKey() - -event = Event("Hello Nostr") -private_key.sign_event(event) - -relay_manager.publish_event(event) -time.sleep(1) # allow the messages to send - -relay_manager.close_connections() diff --git a/draft_code/websocket_raw_nostr_test.py b/draft_code/websocket_raw_nostr_test.py deleted file mode 100644 index e7607077..00000000 --- a/draft_code/websocket_raw_nostr_test.py +++ /dev/null @@ -1,75 +0,0 @@ - -import websocket -import _thread -import time - -def on_open(wsapp): - print(f"on_open works here") - -def on_message(wsapp, message): - print(f"got message: {message[0:20]}") - -def on_ping(wsapp, message): - print("Got a ping! A pong reply has already been automatically sent.") - -def on_pong(wsapp, message): - print("Got a pong! No need to respond") - - -def on_error(wsapp, message): - print(f"Got error: {message}") - - -#wsapp = websocket.WebSocketApp("wss://testnet.binance.vision/ws/btcusdt@trade", on_message=on_message, on_ping=on_ping, on_pong=on_pong, on_error=on_error) - -#wsapp = websocket.WebSocketApp("wss://echo.websocket.events", on_message=on_message, on_ping=on_ping, on_pong=on_pong, on_error=on_error) - -wsapp = websocket.WebSocketApp("wss://relay.damus.io", on_message=on_message, on_ping=on_ping, on_pong=on_pong, on_error=on_error, on_open=on_open) - -#wsapp = websocket.WebSocketApp("wss://relay.primal.net", on_message=on_message, on_ping=on_ping, on_pong=on_pong, on_error=on_error) - - -def stress_test_thread(): - print("before run_forever") - #wsapp.run_forever(ping_interval=30, ping_timeout=10) - #wsapp.run_forever(ping_interval=300, ping_timeout=10, ping_payload="This is an optional ping payload") - wsapp.run_forever() - print("after run_forever") - - -_thread.stack_size(32*1024) -_thread.start_new_thread(stress_test_thread, ()) - - -time.sleep(5) -print("sending it") -# nothing: -#wsapp.send_text('["REQ", "ihopethisworks3", {"kinds": [1], "authors": "04c915daefee38317fa734444acee390a8269fe5810b2241e5e6dd343dfbecc9"}]') -#wsapp.send_text('["REQ", "ihopethisworks3", {"kinds": [1] }]') -# this worked at some point: -#wsapp.send_text('["REQ","index3",{"kinds":[9735]}]') -#wsapp.send_text('["REQ","index3",{"kinds":[9735], "since": 1745086888}]') -tosend = '["REQ","index3",{"kinds":[9735], "since": ' -tosend += str(round(time.time()-100)) -#tosend += str(round(time.time()-2000)) -#tosend += str(round(time.time()-10000)) -tosend += '}]' -print(f"sending: {tosend}") -wsapp.send_text(tosend) -#1745086888 -#["REQ","index",{"kinds":[9735]}] - - -print("waiting 30 seconds...") -time.sleep(30) -#print("sending again") -#wsapp.send_text('again') - - -time.sleep(25) -#print("sending more") -#wsapp.send_text('more') - -wsapp.close() - - diff --git a/draft_code/websocket_raw_nostr_test.py_worked_without_ping_payload b/draft_code/websocket_raw_nostr_test.py_worked_without_ping_payload deleted file mode 100644 index ba0f22fa..00000000 --- a/draft_code/websocket_raw_nostr_test.py_worked_without_ping_payload +++ /dev/null @@ -1,57 +0,0 @@ - -import websocket -import _thread -import time - -def on_message(wsapp, message): - print(f"got message: {message}") - -def on_ping(wsapp, message): - print("Got a ping! A pong reply has already been automatically sent.") - -def on_pong(wsapp, message): - print("Got a pong! No need to respond") - - -def on_error(wsapp, message): - print(f"Got error: {message}") - - -#wsapp = websocket.WebSocketApp("wss://testnet.binance.vision/ws/btcusdt@trade", on_message=on_message, on_ping=on_ping, on_pong=on_pong, on_error=on_error) - -#wsapp = websocket.WebSocketApp("wss://echo.websocket.events", on_message=on_message, on_ping=on_ping, on_pong=on_pong, on_error=on_error) - -wsapp = websocket.WebSocketApp("wss://relay.damus.io", on_message=on_message, on_ping=on_ping, on_pong=on_pong, on_error=on_error) - -#wsapp = websocket.WebSocketApp("wss://relay.primal.net", on_message=on_message, on_ping=on_ping, on_pong=on_pong, on_error=on_error) - - -def stress_test_thread(): - print("before run_forever") - #wsapp.run_forever(ping_interval=30, ping_timeout=10) - wsapp.run_forever(ping_interval=30, ping_timeout=10, ping_payload="This is an optional ping payload") - print("after run_forever") - -_thread.stack_size(32*1024) -_thread.start_new_thread(stress_test_thread, ()) - -time.sleep(5) -print("sending it") -#wsapp.send_text('["REQ", "ihopethisworks3", {"kinds": [1], "authors": "04c915daefee38317fa734444acee390a8269fe5810b2241e5e6dd343dfbecc9"}]') -#wsapp.send_text('["REQ", "ihopethisworks3", {"kinds": [1] }]') -wsapp.send_text('["REQ","index2",{"kinds":[9735]}]') -#["REQ","index",{"kinds":[9735]}] - - -time.sleep(15) -print("sending again") -wsapp.send_text('again') - - -time.sleep(25) -print("sending more") -wsapp.send_text('more') - -wsapp.close() - - diff --git a/draft_code/websocket_raw_nostr_test.py_worked_without_ping_payload_still_works b/draft_code/websocket_raw_nostr_test.py_worked_without_ping_payload_still_works deleted file mode 100644 index 58e5e76c..00000000 --- a/draft_code/websocket_raw_nostr_test.py_worked_without_ping_payload_still_works +++ /dev/null @@ -1,68 +0,0 @@ - -import websocket -import _thread -import time - -def on_message(wsapp, message): - print(f"got message: {message}") - -def on_ping(wsapp, message): - print("Got a ping! A pong reply has already been automatically sent.") - -def on_pong(wsapp, message): - print("Got a pong! No need to respond") - - -def on_error(wsapp, message): - print(f"Got error: {message}") - - -#wsapp = websocket.WebSocketApp("wss://testnet.binance.vision/ws/btcusdt@trade", on_message=on_message, on_ping=on_ping, on_pong=on_pong, on_error=on_error) - -#wsapp = websocket.WebSocketApp("wss://echo.websocket.events", on_message=on_message, on_ping=on_ping, on_pong=on_pong, on_error=on_error) - -wsapp = websocket.WebSocketApp("wss://relay.damus.io", on_message=on_message, on_ping=on_ping, on_pong=on_pong, on_error=on_error) - -#wsapp = websocket.WebSocketApp("wss://relay.primal.net", on_message=on_message, on_ping=on_ping, on_pong=on_pong, on_error=on_error) - - -def stress_test_thread(): - print("before run_forever") - #wsapp.run_forever(ping_interval=30, ping_timeout=10) - #wsapp.run_forever(ping_interval=300, ping_timeout=10, ping_payload="This is an optional ping payload") - wsapp.run_forever() - print("after run_forever") - -_thread.stack_size(32*1024) -_thread.start_new_thread(stress_test_thread, ()) - -time.sleep(5) -print("sending it") -# nothing: -#wsapp.send_text('["REQ", "ihopethisworks3", {"kinds": [1], "authors": "04c915daefee38317fa734444acee390a8269fe5810b2241e5e6dd343dfbecc9"}]') -#wsapp.send_text('["REQ", "ihopethisworks3", {"kinds": [1] }]') -# this worked at some point: -#wsapp.send_text('["REQ","index3",{"kinds":[9735]}]') -#wsapp.send_text('["REQ","index3",{"kinds":[9735], "since": 1745086888}]') -tosend = '["REQ","index3",{"kinds":[9735], "since": ' -tosend += str(round(time.time()-1000)) -tosend += '}]' -print(f"sending: {tosend}") -wsapp.send_text(tosend) -#1745086888 -#["REQ","index",{"kinds":[9735]}] - - -print("waiting 30 seconds...") -time.sleep(30) -#print("sending again") -#wsapp.send_text('again') - - -time.sleep(25) -#print("sending more") -#wsapp.send_text('more') - -wsapp.close() - - diff --git a/internal_filesystem/builtin/apps/com.micropythonos.osupdate/assets/osupdate.py b/internal_filesystem/builtin/apps/com.micropythonos.osupdate/assets/osupdate.py index 317c18a5..a613d52c 100644 --- a/internal_filesystem/builtin/apps/com.micropythonos.osupdate/assets/osupdate.py +++ b/internal_filesystem/builtin/apps/com.micropythonos.osupdate/assets/osupdate.py @@ -81,6 +81,7 @@ class OSUpdate(Activity): def handle_update_info(self, version, download_url, changelog): label = f"Installed OS version: {mpos.info.CURRENT_OS_VERSION}\n" if compare_versions(version, mpos.info.CURRENT_OS_VERSION): + #if True: # for testing label += "Available new" self.install_button.remove_state(lv.STATE.DISABLED) self.install_button.add_event_cb(lambda e, u=download_url: self.install_button_click(u), lv.EVENT.CLICKED, None)