Files

137 lines
6.9 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""Pannello LED iPIXEL: scritte, immagini, luminosità, orologio, accensione. Lo stato di LuZa e le notifiche
compaiono da soli se l'opzione è attiva nelle impostazioni (scheda Casa)."""
from __future__ import annotations
import sys
from pathlib import Path
sys.path.insert(0, str(Path(__file__).resolve().parent.parent))
from avatar import ipixel # noqa: E402
def _p():
if ipixel.panel is None:
raise RuntimeError("pannello iPIXEL non attivo: abilitalo nelle impostazioni (scheda Casa)")
return ipixel.panel
def scrivi(params: dict, ctx: dict) -> str:
testo = str(params.get("testo") or "").strip()
if not testo:
return "Errore: serve il testo."
col = ipixel.NOMI_COLORI.get(str(params.get("colore") or "").lower(), None)
durata = float(params.get("secondi") or 30)
_p().show_text(testo, col, durata)
return f"Sul pannello: «{testo}» per {int(durata)} secondi."
def immagine(params: dict, ctx: dict) -> str:
path = str(params.get("percorso") or "").strip()
if not Path(path).expanduser().is_file():
return "Errore: file immagine non trovato."
_p().show_image(str(Path(path).expanduser()), float(params.get("secondi") or 30))
return "Immagine inviata al pannello."
def luminosita(params: dict, ctx: dict) -> str:
v = max(1, min(int(params.get("livello") or 40), 100))
_p().run_cmd([5, 0, 4, 0x80, v])
_p().settings.set("ipixel_luminosita", v); _p().settings.save()
return f"Luminosità del pannello al {v}%."
def accendi(params: dict, ctx: dict) -> str:
on = str(params.get("acceso", True)).lower() not in ("false", "0", "no")
_p().run_cmd([5, 0, 7, 1, 1 if on else 0])
return "Pannello acceso." if on else "Pannello spento."
def orologio(params: dict, ctx: dict) -> str:
_p().clock()
return "Il pannello mostra l'orologio."
def stato(params: dict, ctx: dict) -> str:
p = ipixel.panel
if p is None:
return "Pannello iPIXEL disattivato nelle impostazioni."
return (f"Pannello {'collegato' if p.connected else 'non collegato'} ({p.size[0]}×{p.size[1]})" + (f", errore: {p.error}" if p.error and not p.connected else "") + ".")
def animazione(params: dict, ctx: dict) -> str:
from avatar import ipixel_fun as fun
import time
nome = str(params.get("nome") or "").lower()
p = _p()
if nome in fun.ANIMAZIONI:
data = fun.ANIMAZIONI[nome](p.size)
with p._lock:
p._want = (f"fun:{time.time()}", data, True); p._notify_until = time.time() + float(params.get("secondi") or 15)
p._shown_key = None; p._poke()
return f"Animazione «{nome}» sul pannello."
kind, val = fun.scegli(p.size)
if kind == "gif":
with p._lock:
p._want = (f"fun:{time.time()}", val, True); p._notify_until = time.time() + 15
p._shown_key = None; p._poke(); return "Sorpresa animata sul pannello."
p.show_text(str(val), None, 12)
return f"Sul pannello: «{val}»."
def demo(params: dict, ctx: dict) -> str:
"""Sequenza dimostrativa sul pannello, in background (circa 90 secondi)."""
import threading, time
from avatar import ipixel_fun as fun
def run():
p = _p()
steps = [
("stato", "THINKING · penso", 4), ("stato", "THINKING · genero la risposta · 42 token · 38/s", 3),
("stato", "THINKING · genero la risposta · 187 token · 51/s", 3), ("stato", "PROCESSING · strumento: meteo", 4),
("stato", "SPEAKING", 4), ("stato", "LISTENING", 3),
("testo", "WA Valentina: amo stasera ceniamo fuori?", 10), ("allarme", "Server i5: disco al 91%", 9),
("anim", "plasma", 7), ("anim", "pacman", 7), ("anim", "cuore", 6), ("anim", "matrix", 6),
("testo", "Più bpm, meno stress", 8), ("musica", "", 22), ("fine", "", 0),
]
for kind, val, dur in steps:
if kind == "stato":
p.on_state(val)
elif kind in ("testo", "allarme"):
p.show_text(val, ipixel.COLORI["ALERT"] if kind == "allarme" else None, dur, icon=ipixel.COLORI["ALERT"] if kind == "allarme" else None)
elif kind == "anim":
data = fun.ANIMAZIONI[val](p.size)
with p._lock:
p._want = (f"demo:{val}:{time.time()}", data, True); p._notify_until = time.time() + dur
p._shown_key = None; p._poke()
elif kind == "musica":
p.on_state("LISTENING")
with p._lock:
p._notify_until = 0; p._want = None
p.set_background("demo:music", ipixel.render_music("Bohemian Rhapsody", "Queen", 61, 354, p.size, dur), True, dur)
elif kind == "fine":
p.clear_background(); p.clock()
time.sleep(dur)
threading.Thread(target=run, daemon=True, name="ipixel-demo").start()
return "Demo avviata sul pannello: stati di LuZa, notifiche, animazioni e schermata musica, circa un minuto e mezzo."
TOOLS = [
{"name": "ipixel_demo", "description": "Mostra una demo sul pannello LED: stati di LuZa e token, notifiche, animazioni, schermata musica.",
"parameters": {"type": "object", "properties": {}}, "run": demo},
{"name": "ipixel_animazione", "description": "Mostra un'animazione sul pannello LED: plasma, matrix, stelle, cuore, equalizzatore, pacman; senza nome una sorpresa a caso (frase spiritosa, info o animazione).",
"parameters": {"type": "object", "properties": {"nome": {"type": "string"}, "secondi": {"type": "number"}}}, "run": animazione},
{"name": "ipixel_scrivi", "description": "Scrive un testo sul pannello LED iPIXEL (scorre se è lungo) per alcuni secondi, poi torna all'orologio. colore: rosso, verde, blu, azzurro, giallo, arancione, viola, rosa, bianco, ciano.",
"parameters": {"type": "object", "properties": {"testo": {"type": "string"}, "colore": {"type": "string"}, "secondi": {"type": "number"}}, "required": ["testo"]}, "run": scrivi},
{"name": "ipixel_immagine", "description": "Mostra un'immagine (percorso di un file) ridimensionata sul pannello LED.",
"parameters": {"type": "object", "properties": {"percorso": {"type": "string"}, "secondi": {"type": "number"}}, "required": ["percorso"]}, "run": immagine},
{"name": "ipixel_luminosita", "description": "Imposta la luminosità del pannello LED (1-100).",
"parameters": {"type": "object", "properties": {"livello": {"type": "integer"}}, "required": ["livello"]}, "run": luminosita},
{"name": "ipixel_accendi", "description": "Accende o spegne il pannello LED (acceso=true/false).",
"parameters": {"type": "object", "properties": {"acceso": {"type": "boolean"}}}, "run": accendi},
{"name": "ipixel_orologio", "description": "Riporta il pannello LED all'orologio.",
"parameters": {"type": "object", "properties": {}}, "run": orologio},
{"name": "ipixel_stato", "description": "Dice se il pannello LED è collegato e la sua risoluzione.",
"parameters": {"type": "object", "properties": {}}, "run": stato},
]