-
Notifications
You must be signed in to change notification settings - Fork 1
Description
MeticulousHome Repository Research — Findings & Impact Analysis
Comprehensive analysis of 13 repositories in the MeticulousHome GitHub organization and their relevance to MeticAI's current and planned milestones.
Executive Summary
| Category | Repos | Key Finding |
|---|---|---|
| Direct dependencies | espresso-api, espresso-profile |
TS packages ready for milestone 2.4 Capacitor app |
| Reference implementations | meticulous-dial, meticulous-web-ui |
Production-proven React + Socket.IO patterns |
| Ground truth | meticulous-backend |
Complete API surface (38+ endpoint groups, 12+ Socket.IO events) |
| Current backend | pyMeticulous |
v0.3.1 with 55 methods — verify MeticAI uses latest |
| Content sources | ProfileDefaults, ProfileDefaultImages |
Default profiles + images for UI theming |
| Schema standard | espresso-profile-schema |
Canonical JSON Schema (Draft-07) for profile validation |
Critical Findings for Planned Milestones
Milestone 2.3 — "Run Without Saving" Confirmed
Issue #281 (Temporary Variable Adjustments) is fully supported by the machine API:
-
meticulous-dial has a working "Brew Once" implementation in
PressetSettings.tsx:- Clones profile -> applies local edits -> loads via API -> starts brew -> never saves
- This is exactly the UX pattern we designed in feat: temporary variable adjustments when running a shot #281
-
meticulous-backend confirms the mechanism:
POST /api/v1/profile/loadaccepts inline profile JSON (loaded to machine, NOT persisted)POST /api/v1/profile/saveis a separate call (only called when user explicitly saves)- The "run without saving" = load modified profile without calling save
-
Variable system is well-defined:
- 6 types:
pressure,flow,weight,power,time,piston_position - Variables referenced as
$keyin stages, dynamics, exit triggers, and limits processProfileVariables()in espresso-profile resolves all references
- 6 types:
Milestone 2.4 — Capacitor App Has Ready-Made Dependencies
Issue #253 (iOS Capacitor app) can leverage:
-
@meticulous-home/espresso-api(v0.10.11, npm)- 47+ methods covering ALL machine operations
- Socket.IO client built-in for real-time telemetry
- Actively maintained (last commit: Feb 18, 2026)
- Can replace our Python-to-REST bridge entirely for client-side operations
-
@meticulous-home/espresso-profile(v0.4.2, npm)- Zero runtime dependencies — pure TypeScript types
- Profile parsing, variable resolution, reference tracking
- Directly usable in our React/TypeScript web app
-
Issue Introduce MachineService abstraction layer for multi-backend support #252 (MachineService abstraction) becomes clearer:
espresso-apialready provides the adapter pattern we need- MachineService can wrap
espresso-apifor the Capacitor/direct path - Current Python backend path wraps
pyMeticulous(same API, different runtime)
New Features Discovered
| Feature | Source Repo | Milestone | Priority |
|---|---|---|---|
| Decent profile conversion | met-community-profiles (DecentConverter) |
Backlog (#284) | Medium |
| Decent profile link import | Decent Espresso websites | Backlog (#284) | Medium |
| Profile default images | ProfileDefaultImages |
2.3 | Low |
| Sound theme management | meticulous-backend |
2.4+ | Low |
| WiFi management UI | meticulous-backend + meticulous-web-ui |
2.4+ | Low |
Repository-by-Repository Analysis
1. meticulous-typescript-api (CRITICAL)
Package: @meticulous-home/espresso-api v0.10.11 | Stars: 14 | License: GPL-3.0
| Aspect | Details |
|---|---|
| Status | Actively maintained (Feb 2026) |
| Methods | 47+ covering: profiles, history, machine control, settings, WiFi, sounds, firmware, notifications |
| Real-time | Socket.IO with 6 event types: status, sensors, communication, actuators, profile_update, notification |
| Dependencies | axios, socket.io-client, @meticulous-home/espresso-profile |
| Types | Full TypeScript definitions for all data structures |
Action Types: start, stop, continue, reset, tare, preheat, calibration, scale_master_calibration
Missing from enum: abort, purge, home (present in pyMeticulous/backend)
MeticAI Impact:
- 2.4: Direct dependency for Capacitor app — replaces need for Python proxy for client-side ops
- 2.3: Can validate our profile variable handling against their implementation
- Gap: Missing
abort/purge/homeactions vs pyMeticulous — may need supplemental calls
Forks: 4 forks (ohheyitsdave, kenschwartz, erdos2n, rorymc) — all plain copies, no divergent work.
2. meticulous-typescript-profile (CRITICAL)
Package: @meticulous-home/espresso-profile v0.4.2 | Stars: 7 | License: GPL-3.0
| Aspect | Details |
|---|---|
| Dependencies | ZERO runtime deps (pure types + utils) |
| Types | Profile, Stage, Variable, Dynamics, ExitTrigger, Limit + all sub-types |
| Functions | parseProfile(), processProfileVariables(), findVariableReferences(), buildProfileMap() |
| Validation | Custom (FormatException, UndefinedVariableException, VariableTypeException) |
Variable Types: power, flow, pressure, weight, time, piston_position
MeticAI Impact:
- 2.3: Use
findVariableReferences()for the variable editing UI — shows which stages use each variable - 2.3: Use
processProfileVariables()to resolve variables before sending to machine - 2.4: Direct import into Capacitor web app for type-safe profile handling
- Missing: No clone/diff/merge utilities — we'll need to add these for profile editing
3. espresso-profile-schema (HIGH)
Format: JSON Schema Draft-07 + RFC document | Stars: 10 | License: GPL-3.0
Key schema constraints:
temperature: 0-100 Cfinal_weight: 0-2000g- Stages must have >=1 item, each with dynamics + exit_triggers
- Display: image (URI-reference), accentColor (
#RRGGBB), shortDescription (<=100 chars) - Variables: key (string), type (enum), value (number)
Status: Draft/evolving. RFC explicitly states "unfinished, public for discussion basis."
Future direction: BEANS DSL for Turing-complete profile logic.
MeticAI Impact:
- Now: Validate our profile generation against the canonical schema
- 2.3: Ensure variable editing respects schema constraints (types, ranges)
- 2.4: Bundle schema for client-side validation in Capacitor app
4. meticulous-backend (CRITICAL — Ground Truth)
Framework: Tornado + Socket.IO | Port: 8080
Complete API surface — 38+ endpoint groups:
Profile Management:
GET/POST /api/v1/profile/list— List profiles (with?full=true)GET/POST /api/v1/profile/defaults— Default profilesPOST /api/v1/profile/save— Save profile (X-Change-Id header for sync)GET/POST /api/v1/profile/load— Load profile to machine (inline JSON or by ID)GET /api/v1/profile/get/{id}— Get single profileDELETE /api/v1/profile/delete/{id}— Delete profileGET /api/v1/profile/changes— Change historyGET /api/v1/profile/last— Last loaded profileGET /api/v1/profile/image/...— Profile imagesGET /api/v1/profile/legacy— Legacy JSON format
History & Analytics:
GET/POST /api/v1/history— Search shots (query, dates, IDs, sorting)GET /api/v1/history/current— Currently brewing shotGET /api/v1/history/last— Last completed shotGET /api/v1/history/stats— Aggregated statisticsPOST /api/v1/history/rating/{id}— Rate shotGET /api/v1/history/debug— Debug file listing
Machine Control:
POST/GET /api/v1/action/{action}— Execute action- ESP:
start,stop,tare,purge,home - Backend:
reset,abort
- ESP:
Settings, WiFi, Sounds, Firmware, Notifications, Timezone, Manufacturing — all fully documented
Socket.IO Events (12+):
status (100ms updates), sensors, button, notification, profileHover, profile, heater_status, water_status, OSUpdate, communication, actuators
Key architectural insights:
- Profile sync via
X-Change-Idheader for conflict resolution - Shot files stored as
.zst(Zstandard) with auto-decompression - Button events map hardware gestures to software actions
profileHoverenables multi-client sync (dial + iOS app + web)
MeticAI Impact:
- Now: Verify our pyMeticulous usage covers all endpoints we need
- 2.3: Confirms "run without saving" =
POST /api/v1/profile/loadwith inline JSON - 2.4: Ground truth for MachineService abstraction (Introduce MachineService abstraction layer for multi-backend support #252)
- Gap:
profileHoversync — we should implement this for multi-client support
5. pyMeticulous (CRITICAL — Current Backend)
Package: pyMeticulous v0.3.1 | Stars: 7 | License: GPL-3.0 | Last update: Jan 17, 2026
55 methods across: profiles (11), actions (7), settings (2), WiFi (8), sounds (6), device (6), history (14), notifications (2), system (10), Socket.IO (2)
Action types (superset of TS API): START, STOP, CONTINUE, RESET, TARE, PREHEAT, SCALE_MASTER_CALIBRATION, HOME, PURGE, ABORT
Key features beyond TS API:
import_profiles(file_path)— Bulk importload_legacy_profile(data)— Legacy format supportdelete_history_entry(shot_id)— History deletionexport_history()— Full history export- Event throttling (global or per-event)
- Pydantic models for all data structures
MeticAI Impact:
- Now: Verify we're on v0.3.1 and using all available features
- 2.3:
load_profile_from_json()is the "run without saving" method - 2.4: pyMeticulous stays as server-side adapter; espresso-api becomes client-side adapter
- Gap: pyMeticulous has
ABORT,PURGE,HOMEactions that TS API lacks
6. meticulous-dial (HIGH — Reference UI)
Framework: Tauri 2.9 + React 18 + Redux + Socket.IO | License: MIT | Branch: beta
40+ components for the machine's touchscreen (480x480 circular display).
"Brew Once" implementation (our #281 reference):
PressetSettings.tsx -> activeSetting.key === 'brew_once'
1. Clone profile with current edits
2. loadProfileData(modified_profile) // Loads to machine, not saved
3. startProfile() // Begin brewing
4. Navigate back to profile home // Edits discarded
Patterns worth adopting:
- Redux + React Query hybrid (local UI state + server state)
- ProfileContext for complex multi-level state
- Custom event bus (HandleEvents) for gesture/action decoupling
- Socket.IO query invalidation on events
- Transactional profile editing (all-or-nothing save)
profileHovermulti-client sync- Idle timer with reduced polling (2s -> 60s)
MeticAI Impact:
- 2.3: Direct reference for "Brew Once" / temporary variable implementation
- 2.4: Architecture patterns for Capacitor app (especially Socket.IO + state management)
7. meticulous-web-ui (HIGH — Reference UI)
Framework: React 19 + Vite 7 + TailwindCSS 4 + ECharts | License: MIT | Last update: Feb 2026
On-machine debug/settings UI. Not for shot control — settings and monitoring only.
Patterns worth adopting:
- Socket.IO Context + React Query hybrid
- Responsive hooks (useDevice()) for mobile/desktop adaptation
- ECharts for real-time monitoring charts
- Partial settings updates (only send changed fields)
- BottomModal/Sheet pattern for settings
- Profile drag-drop reordering (@dnd-kit)
MeticAI Impact:
- 2.4: Closest tech stack match (React 19, Vite 7, TailwindCSS 4) — best reference for Capacitor app
- Now: Settings management patterns applicable to our existing Settings view
8. meticulous-settings-ui (MODERATE)
Framework: React 19 + Bootstrap 5.3 + TanStack Query 5 | Very early stage (4 commits, May 2025)
Dynamic form generation from backend settings response. Uses @dnd-kit for drag-drop.
MeticAI Impact: Limited — early stage, Bootstrap (we use Tailwind). Dynamic form generation pattern is interesting but our settings are more complex.
9. met-community-profiles (MODERATE — Reference)
Framework: VitePress + Vue 3 + Plotly.js
Note: This repo no longer holds community profiles of note. Its primary value is as a reference for:
DecentConverter.vue— Converts Decent Espresso profiles to Meticulous format (valuable logic to port)- Plotly.js profile visualization patterns
MeticAI Impact:
- Backlog (feat: Decent Espresso profile import & URL link conversion #284): Port DecentConverter logic + add Decent profile link import
- Future: Profile visualization improvements using Plotly patterns
10. ProfileDefaults (MODERATE)
7 default profiles (4 core + 3 community) in schema-compliant JSON. Numeric prefix naming for ordering.
MeticAI Impact: Seed data for fresh installations, reference for profile structure validation.
11. ProfileDefaultImages (MODERATE)
25 PNG thumbnails (106-254KB) + accent_colors.json mapping MD5 hashes to hex accent colors.
MeticAI Impact: Profile theming in UI, image selection during profile creation/editing.
12. meticulous-watcher (LOW)
Health monitoring service (Tornado port 3000). Monitors 7 services, reports disk/memory/uptime.
MeticAI Impact: Could integrate /status endpoint for machine health display.
13. GatewayPi (LOW)
KivyMD + WireGuard gateway for Raspberry Pi. Network status display.
MeticAI Impact: Minimal — different deployment model. WireGuard patterns potentially useful for remote access features.
API Parity Analysis: pyMeticulous vs espresso-api
| Feature | pyMeticulous (Python) | espresso-api (TypeScript) | Gap |
|---|---|---|---|
| Profile CRUD | 11 methods | 10 methods | TS missing import_profiles, load_legacy |
| Actions | START, STOP, CONTINUE, RESET, TARE, PREHEAT, CALIBRATION, HOME, PURGE, ABORT |
Missing HOME, PURGE, ABORT |
Gap in TS |
| History | 14 methods (incl. delete, export) | 8 methods | TS missing delete, export, file-level access |
| Settings | Full | Full | Parity |
| WiFi | 8 methods | 8 methods | Parity |
| Sounds | 6 methods | 6 methods | Parity |
| Socket.IO | 12+ events, throttling | 6 events | TS has fewer typed events |
| Firmware | Yes | Yes | Parity |
| Notifications | Yes | Yes | Parity |
| Bulk import | Yes | No | Gap in TS |
| Event throttling | Yes | No | Gap in TS |
Recommendation: For milestone 2.4 Capacitor app, use espresso-api as base but supplement with direct REST calls for missing features (abort, purge, home, history export).
Recommendations and Action Items
Immediate (v2.2.0)
- Verify MeticAI's pyMeticulous version matches v0.3.1 — Confirmed:
>=0.3.1pinned, v0.3.1 installed - Validate our profile generation against
espresso-profile-schemaJSON Schema — Already implemented:validation_service.pyusesProfileValidatorwith schema cloned at Docker build time fromMeticulousHome/espresso-profile-schema - Check if we handle
profileHoverevents (multi-client sync) — Not handled: pyMeticulous exposessend_profile_hover()but MeticAI does not use it. Socket.IO events are available but unused; MeticAI uses REST + MQTT instead. Multi-client sync via profileHover is a future enhancement.
Milestone 2.3
- Use meticulous-dial's "Brew Once" as reference implementation for feat: temporary variable adjustments when running a shot #281
- Add
@meticulous-home/espresso-profileto web app deps for variable utilities - Port DecentConverter logic for Decent profile import (feat: Decent Espresso profile import & URL link conversion #284)
- Add profile default images support from ProfileDefaultImages
Milestone 2.4
- Add
@meticulous-home/espresso-apias primary client-side dependency - Design MachineService (Introduce MachineService abstraction layer for multi-backend support #252) with two adapters:
PythonProxyAdapter— current path through our FastAPI backendMachineDirectAdapter— uses espresso-api for direct machine communication
- Adopt Socket.IO + React Query hybrid pattern from meticulous-web-ui
- Handle API gaps (abort, purge, home) with direct REST supplementation
New Issues to Consider
- Sound theme management (API fully supports it)
- WiFi management UI (all CRUD endpoints available)
- Machine health dashboard (meticulous-watcher integration)
- Profile image support (accent colors, thumbnails)
Research conducted: Session analysis of 13 MeticulousHome repositories with deep-dive into source code, API surfaces, type definitions, and architectural patterns.