Files
Adolfo Reyna e68909d64d
Main / Build (BookPlayer) (push) Has been cancelled
Main / Build (Brainfuck) (push) Has been cancelled
Main / Build (Breakout) (push) Has been cancelled
Main / Build (Calculator) (push) Has been cancelled
Main / Build (Diceware) (push) Has been cancelled
Main / Build (EpubReader) (push) Has been cancelled
Main / Build (GPIO) (push) Has been cancelled
Main / Build (GraphicsDemo) (push) Has been cancelled
Main / Build (HelloWorld) (push) Has been cancelled
Main / Build (M5UnitTest) (push) Has been cancelled
Main / Build (Magic8Ball) (push) Has been cancelled
Main / Build (MediaKeys) (push) Has been cancelled
Main / Build (MystifyDemo) (push) Has been cancelled
Main / Build (SerialConsole) (push) Has been cancelled
Main / Build (Snake) (push) Has been cancelled
Main / Build (TamaTac) (push) Has been cancelled
Main / Build (TodoList) (push) Has been cancelled
Main / Build (TwoEleven) (push) Has been cancelled
Main / Bundle (push) Has been cancelled
chore: move app skill in-repo + AGENTS.md
- Migrates tactility-app-development from ~/.hermes/skills/ into
  .claude/skills/ for repo co-location
- Adds AGENTS.md with local workstation context, hardware table,
  board-direct build/env wrapper (PYTHONPATH fix), ELF missing-symbol
  triage, app patterns (immersive, QVGA rail, tutorial 2-row,
  GameKit bubbling, screenshot rate-limit), and skill index

Refs: personal Gitea mirror
2026-07-17 09:51:20 -04:00

2.9 KiB

Deploy & Run on Device (v0.7+ Dashboard)

Board Discovery (.112 case)

User said "ip ending on 112". Local subnet found via ifconfig -> 192.168.68.114/24, so target is 192.168.68.112.

Discovery recipe:

arp -a | grep 112
# ping sweep
for cand in 192.168.68.112 192.168.1.112 192.168.0.112; do
  ping -c1 -W 500 $cand
  curl -m2 -s http://$cand/ | head
done

Found: port 80 responds with HTTP 302 -> /dashboard.html. Port 6666 (old dev port) Connection refused.

Install Endpoint Change

tactility.py (tool v3.5.1) still tries POST http://<ip>:6666/app/install. That requires Developer mode enabled on device (Settings > Development > Enable dev server). When disabled, install fails with:

❌ Install request failed: HTTPConnectionPool(host='192.168.68.112', port=6666): ... Connection refused

Firmware v0.7.0-dev Dashboard is on port 80 with new API:

  • Discovered via browser devtools / document.documentElement.innerHTML JS fetch search:
    • GET /api/apps -> list
    • PUT /api/apps/install multipart field file
    • POST /api/apps/run?id=<appId>
    • POST /api/apps/uninstall?id=<appId>
    • /api/sysinfo, /api/screenshot, etc.

Working install via curl / python

curl http://192.168.68.112/api/apps | jq

# PUT, not POST
curl -X PUT http://192.168.68.112/api/apps/install \
  -F "file=@build/BibleVerse.app;type=application/octet-stream"
# => 200 ok

Python:

import requests, pathlib
ip="192.168.68.112"
path="build/BibleVerse.app"
with open(path,'rb') as f:
    r=requests.put(f"http://{ip}/api/apps/install",
                   files={'file': ('BibleVerse.app', f, 'application/octet-stream')},
                   timeout=120)
    print(r.status_code, r.text[:500])
# run
requests.post(f"http://{ip}/api/apps/run?id=one.tactility.bibleverse", timeout=10)

Platform Arg Required

tactility.py Apps/MyApp install <ip> without platform tries all manifest platforms (esp32s3,esp32p4) -> fails if only esp32s3 ELF built:

❌ ELF file not built for esp32p4

Fix: always pass platform explicitly matching what you built:

tactility.py Apps/BibleVerse install 192.168.68.112 esp32s3
# or
tactility.py Apps/BibleVerse build esp32s3,esp32p4 --local-sdk   # build all first

Browser Verification Recipe

Use Hermes browser tools:

// navigate to http://<ip>/dashboard.html -> Apps tab
document.documentElement.innerHTML.match(/\/api\/apps[^\s"']*/g)
// returns ["/api/apps", "/api/apps/run?id=", "/api/apps/uninstall?id=", "/api/apps/install"]
// inline scripts contain:
function installAppFile(file) { fetch('/api/apps/install', {method:'PUT', body: formData}) }

This avoids guessing old docs.

Checklist After Install

  • GET /api/apps contains your app id
  • POST /api/apps/run?id= -> 200 ok (app shows on device)
  • If install via dashboard UI: drag .app onto upload zone works same as PUT