Files
MicroPythonOS/draft_code/saved_functions.py
T
Thomas Farstrike 3e245f66a3 saved functions
2025-06-14 11:52:19 +02:00

728 lines
17 KiB
Python

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