Install
openclaw skills install earl-display-controlManage Earl's TV dashboard (VisuoSpatial Sketchpad) — wake the display, restart the local server, launch the kiosk browser, and update Earl's mind (mood, hou...
openclaw skills install earl-display-controlSkill for managing the VisuoSpatial Sketchpad — Earl's living-room TV dashboard. This covers starting the HTTP server, launching the kiosk browser, and updating earl_mind.json via the Python API.
All file paths below use {baseDir} to mean this skill's root directory (the repo root containing VisuoSpatialSketchpad/).
GET /earl_mind.json ... 200 in the server logEarlMind API from {baseDir}/VisuoSpatialSketchpad/earl_api.pyStart the HTTP server from the VisuoSpatialSketchpad directory:
cd {baseDir}/VisuoSpatialSketchpad && python3 -m http.server 8000
Background the process so the shell prompt returns.
macOS / Linux:
lsof -ti:8000 | xargs kill -9
Windows (PowerShell):
Get-Process -Id (Get-NetTCPConnection -LocalPort 8000).OwningProcess | Stop-Process -Force
macOS:
open -a "Google Chrome" --args --kiosk http://localhost:8000/sketchpad.html
If Chrome is unavailable, Safari works too:
open -a Safari http://localhost:8000/sketchpad.html
Windows (PowerShell):
Start-Process msedge.exe '--kiosk http://localhost:8000/sketchpad.html --edge-kiosk-type=fullscreen'
Linux:
xdg-open http://localhost:8000/sketchpad.html
Or for a true kiosk with Chromium:
chromium-browser --kiosk http://localhost:8000/sketchpad.html
Always relaunch after a wake cycle — the browser may cache the old page.
All methods live in {baseDir}/VisuoSpatialSketchpad/earl_api.py. Run from the VisuoSpatialSketchpad directory:
from earl_api import EarlMind
mind = EarlMind()
Each mutating method auto-saves and bumps meta.last_updated / meta.update_count.
| Method | Purpose | Key Parameters |
|---|---|---|
set_mood(mood, energy, vibe, expression) | Set Earl's mood and inner monologue | mood: str, energy: 0-1 float, vibe: str, expression: str |
set_photo(url, caption) | Set Earl's header photo | url: str (URL or local path), caption: str |
post_house_stuff(title, detail, priority, category, icon) | Add a household reminder | priority: "high"/"medium"/"low", icon: emoji str |
resolve_house_stuff(item_id) | Remove a resolved item by ID | item_id: str (e.g. "hs_a1b2c3") |
clear_house_stuff() | Clear all house stuff items | — |
update_room(room_id, status, notes, attention) | Update a room's state | attention: 0-1 float |
add_room(room_id, name, x, y, icon, status, notes, attention) | Add a new room | x, y: 0-1 normalized position |
sweep() | Log a full house sweep | — |
hot_take(topic, take, heat, emoji) | Add or update a hot take | heat: 0-1 float, updates if topic exists |
drop_take(topic) | Remove a hot take by topic | — |
doodle(label, x, y, size, color, note) | Place an emoji doodle on the sketchpad | x, y: 0-1, size: px, color: hex |
sketch_note(text, x, y, size, color) | Place a text note on the sketchpad | Same as doodle |
clear_sketchpad() | Wipe the sketchpad clean | — |
learn_pattern(pattern, confidence, observations) | Record a long-term pattern | confidence: 0-1, observations: int |
summary() | Get a human-readable state summary | Returns str |
snapshot() | Get the raw mind dict | Returns dict |
# Set mood
mind.set_mood("happy", energy=0.9, vibe="Sun's out, vibes are immaculate.")
# Post a house reminder
mind.post_house_stuff("Bins go out tonight", detail="Wednesday again.", priority="high", category="chores", icon="🗑️")
# Drop a hot take
mind.hot_take("Pineapple on pizza", "Controversial but I respect the audacity.", heat=0.6, emoji="🍕")
# Doodle on the sketchpad
mind.doodle("🌧️", x=0.3, y=0.2, size=30, note="Rain starting")
# Log a pattern
mind.learn_pattern("The cat sits by the window at 3pm", confidence=0.7, observations=5)
Run the weather helper to fetch live Open-Meteo data, update mood/energy, and drop a weather doodle:
cd {baseDir}/VisuoSpatialSketchpad && python3 update_weather_ping.py
The dashboard reads {baseDir}/VisuoSpatialSketchpad/earl_mind.json. Top-level structure:
{
"identity": { name, role, mood, energy (0-1), current_vibe, avatar_expression, photo, photo_caption }
"spatial_awareness": { house_name, location: { latitude, longitude, timezone, temperature_unit, wind_speed_unit }, last_sweep, rooms: [...] }
"house_stuff": { items: [{ id, title, detail, priority, category, icon }] }
"earl_unplugged": [{ id, topic, take, heat (0-1), emoji, date }]
"sketchpad": { canvas: [{ id, type ("doodle"|"note"), label, x, y, size, color, note }] }
"long_term_patterns": [{ pattern, confidence (0-1), observations }]
"meta": { schema_version, last_updated (ISO 8601), update_count }
}
If you edit JSON directly, always bump meta.last_updated and meta.update_count, and write with ensure_ascii=False, indent=2.
lsof -i:8000. On Windows: Get-Process python.pkill -f "Google Chrome". Windows: taskkill /IM msedge.exe /F.spatial_awareness.location.latitude and longitude are set (not 0.0) in earl_mind.json.VisuoSpatialSketchpad directory, or add it to sys.path.Restart server -> launch kiosk -> apply content changes -> relaunch kiosk if needed. Follow this every time the house texts "wake up".