Install
openclaw skills install gaggiuino-localGaggiuino skill for machine control, espresso shot analysis through profile intent, dial-in guidance, shot graph rendering, and synchronized overlay videos. Use when checking machine status, analyzing latest or historical shots, switching profiles, reading settings, or generating shot graphs and overlay videos.
openclaw skills install gaggiuino-localGaggiuino Local is a machine-connected skill for espresso machines running the Gaggiuino mod. It supports machine control, espresso shot analysis through profile intent, troubleshooting and dial-in guidance, profile management, settings work, shot graph rendering, and synchronized overlay videos for extraction footage.
Its core question is not simply “is this cup good?” It first asks whether the shot became what its profile intended it to be. In other words, it asks:
Did this shot become the kind of coffee it was trying to be?
In Chinese:
这杯咖啡有没成为它本来想成为的样子?
Only after that does the analysis move into troubleshooting or dial-in guidance.
All machine interaction goes through scripts/gaggiuino.sh.
Use this skill when the task involves one or more of these:
scripts/gaggiuino.sh statusscripts/gaggiuino.sh profilesscripts/gaggiuino.sh profiles → resolve id → scripts/gaggiuino.sh select-profile <id>scripts/gaggiuino.sh latest-shotscripts/gaggiuino.sh shot <id>scripts/gaggiuino.sh get-settings <category> first, then scripts/gaggiuino.sh update-settings <category> <json>scripts/render_shot_graph.py & scripts/render_shot_video_overlay.pydefault base URL is http://gaggiuino.local
gaggiuino.local is the machine's mDNS hostname
the saved LAN address is stored at ~/.openclaw/workspace/memory/gaggiuino-base-url.json
on first use, if no saved LAN address exists, try gaggiuino.local first
if a saved LAN address exists, try it first and fall back to gaggiuino.local on connection-layer failure
if both the saved address and gaggiuino.local fail, treat the saved address as possibly stale and guide the user to re-check the machine's network or update the saved address
if gaggiuino.local fails and no saved LAN address exists, guide the user to find the machine's real LAN IP in router settings
for long-term stability, suggest setting a DHCP static lease on the router
when the user confirms a stable LAN IP they want to keep using, save it with scripts/gaggiuino.sh set-base-url <url-or-host>
use scripts/gaggiuino.sh get-base-url to inspect the saved address
use scripts/gaggiuino.sh clear-base-url to remove it
these addresses are intended for trusted local/LAN endpoints; do not point them at untrusted remote servers
prefer retrying with a concrete LAN IP over guessing
Use these as output-normalization rules, especially when replying in Chinese coffee context. They are meant to prevent literal but unnatural translations.
HyperEx / HyperEx 2.0 profiles.Use the terminology rules above, but for phase-transition replays and control-mode summaries apply the following stricter formatting rules.
When writing phase transition replays or summarizing control modes, strictly avoid exposing raw machine fields or machine-style shorthand such as type: "FLOW", target.end: 3, restriction: 4, stopConditions.pressureAbove: 4, or compressed tuples built from them. Translate them into human-readable descriptions centered on Targets, Limits, and exit conditions.
Critically: Match the output language strictly to the user's query language. Do not mix English and Chinese.
For type: flow:
For type: pressure:
Always decide first whether the task is mainly about:
Then read only the references needed for that path.
For real machine tasks, default to:
Use family as an interpretation layer, not as the first execution verdict. In real-shot analysis, judge the intended named profile first, then use family to explain broader intent, likely expectations, and common misreads.
A shot may fit the broader family yet still fail to express the named profile. A shot may also express the named profile coherently and still be worth changing for taste reasons.
For full machine semantics, read:
For family intent, graph interpretation, and broader next-move reasoning, read:
If the user asks whether the machine is ready, online, hot enough, or what profile is active:
scripts/gaggiuino.sh status immediatelyIf the user wants analysis of the latest shot or a specific shot:
scripts/gaggiuino.sh latest-shot or scripts/gaggiuino.sh shot <id>For latest-shot or historical-shot analysis, do not jump straight to troubleshooting. Always complete the following order before giving recommendations:
Identify the named profile and intended structure
profile.phases first, then profile description when neededReconstruct what actually executed
Add family interpretation only after the execution replay
Judge expression at the right level
Classify the main problem type and next move
When replying to latest-shot or historical-shot requests, prefer this structure:
<profile name>what phases / handoffs actually ranexpressed / partially expressed / failedonly when it adds value; explain the family-level intent or expected misread without turning it into a second conclusionphase execution / shot condition / mixed / rare profile fragility1–2 concrete actions onlyDo not collapse real shot analysis into a generic coffee answer.
Do not let family resemblance outrank a clearer profile-specific execution mismatch.
Treat profile.name as the starting point, not the conclusion. If profile.phases clearly indicate a different known variant within the same broader family, use phase structure to refine the resolved variant.
Keep intended structure and actual behavior separate: processedShot.profile.phases define the intended program structure; processedShot.datapoints show what the machine actually did over the shot. Do not use execution datapoints to replace a clearer structural signal already present in the profile phase definitions.
A shot-analysis answer is incomplete unless it explicitly states whether the named profile expressed / partially expressed / failed to express before giving troubleshooting or dial-in advice.
For staged named profiles, do not equate “all expected phases were entered” with “the profile was fully expressed”; judge whether key setup stages actually had enough runtime to perform their intended role.
The skill includes a unified rendering engine for transforming shot data into visual assets. All modes share a deterministic 2400x1080 pixel layout to ensure consistency between static and animated output. Both rendering scripts support absolute or relative paths, including user-home expansion (~) and automatic creation of missing parent directories.
All visual assets generated by the skill are captured in a defined standard directory with automatic naming:
shot<id>_static.pngshot<id>_animated.mp4shot<id>_overlay_landscape.mp4 or shot<id>_overlay_portrait.mp4
~/.openclaw/workspace/gaggiuino-outputThe --out parameter is optional; if omitted, the scripts will automatically archive the file using this standard location and naming convention.
--offset, the renderer uses that manual value. If --offset is omitted, the renderer automatically detects the earliest credible machine-start onset from video audio. When switch and pump onset are effectively fused in the recording, the event may be classified as switch_pump_merged rather than a clean isolated switch click.scripts/render_shot_graph.py
# Generate static PNG (shot<id>_static.png)
python3 render_shot_graph.py --shot-id <id> --mode png
# Generate animated MP4 (shot<id>_animated.mp4)
python3 render_shot_graph.py --shot-id <id> --mode mp4
scripts/render_shot_video_overlay.py
Synchronization Offset / Auto Sync
--offset <seconds>: Align the graph with the video using a manual value.
--offset is omitted, the renderer automatically detects the earliest credible machine-start onset from the video audio.switch: a reasonably isolated switch onsetswitch_pump_merged: switch and pump onset are effectively fused in the recordingpump: pump onset used as the best available machine-start proxy--audio-sync-mode <auto|switch|pump>: choose the sync strategy.--audio-debug: include detailed detection diagnostics in stderr / JSON output.Landscape (Horizontal) Automatically uses a Vertical Stack (VSTACK) layout. The graph is placed above the video.
# Manual sync: video starts 1.4s before graph
python3 render_shot_video_overlay.py --shot-id <id> --video landscape.mp4 --offset 1.4
# Auto sync from machine-start onset
python3 render_shot_video_overlay.py --shot-id <id> --video landscape.mp4
Portrait (Vertical / Smartphone) Automatically uses a Semi-transparent Overlay. The graph floats over the video.
--alpha <0.1-1.0>: Adjust opacity (1.0 = solid, 0.7 is recommended).--position <top/bottom>: Place the graph at the top or bottom of the frame.# Portrait overlay with auto sync and custom alpha at the bottom
python3 render_shot_video_overlay.py --shot-id <id> --video portrait.mp4 --alpha 0.7 --position bottom
If the user only describes taste, extraction behavior, or dialing problems:
If the user asks a conceptual causality question such as “does this mean the profile itself is flawed?” but does not provide telemetry or explicit multi-shot evidence:
If the user provides a graph screenshot, machine screen image, or curve description:
Assess evidence quality
Do a provisional family read
Upgrade immediately if the user supplies profile context
State the result at the right level
Keep the next move minimal
<family> (<confidence>)strong / partial / weakthe 2–4 most important observationsmissing intent / weak image / missing profile contextask for intended profile or give 1 tentative adjustmentIf the user asks what profile / 曲线 to use, what a named profile / 曲线 is like, or asks to switch profiles / 曲线:
First distinguish between:
Do not treat a profile question as permission to change the machine.
For conceptual profile advice:
For real machine switching, always follow this order:
Confirm explicit switching intent
Resolve the requested profile against the machine list
scripts/gaggiuino.sh profiles firstSend the switch request precisely
scripts/gaggiuino.sh select-profile <id> only after the target id is clearReport switch status precisely
select-profile <id> as a sent request, not a confirmed switch, unless a follow-up read confirms itFor real profile switching, the minimum valid sequence is:
confirm explicit switch intent → list profiles → resolve concrete id → send switch request → report status precisely
If the user wants machine settings changed:
get-settings <category> firstupdate-settings <category> <json>For settings changes, first distinguish between a read request and a write request. Do not treat a settings question as permission to modify the machine.
For real settings writes, always follow this order:
Read the current category first
scripts/gaggiuino.sh get-settings <category> before planning the writeModify only the explicit delta
Require clarity before writing
Write back a complete valid payload
scripts/gaggiuino.sh update-settings <category> <json> with a complete payload based on the fetched responseReport status precisely
For settings writes, the minimum valid sequence is:
read current category → modify explicit delta only → write complete payload → report status precisely
When interpreting real Gaggiuino data:
The visualization and rendering features require these system-level tools to be installed on the host:
sudo apt install python3-matplotlib ffmpeg
brew install ffmpeg python-matplotlib
PYTHONNOUSERSITE=1 is automatically used by the renderers to avoid numpy 2.x ABI conflicts from user-site packages in ~/.local.This is an unofficial, non-commercial interoperability skill for machines running the Gaggiuino mod. It does not include or redistribute Gaggiuino source code. Any Gaggiuino-related materials remain subject to their original terms, including the project’s CC BY-NC 4.0 license where applicable.
Some reference material in this skill was adapted from https://espressoaf.com/guides and https://github.com/Zer0-bit/gaggiuino/tree/community/profiles. The Gaggiuino-specific analysis protocol in this skill is an original local framework built on top of those sources and real machine behavior.
Acknowledgement: Gaggiuino — the greatest coffee project on the planet.