cncjs-pendant-alexa
v0.2.0
Published
Voice jog control for cncjs via a custom Alexa skill ("Alexa, X plus 20")
Downloads
321
Maintainers
Readme
cncjs-pendant-alexa
Voice jog control for cncjs through a custom Alexa skill:
One-shot: "Alexa, ask mill x plus 20" — or open CNC mode: "Alexa, open mill" … "x plus 20" … "position x 130 y 100" … "close"
One-shot: "Alexa, peça pra fresa xis mais vinte" — ou modo CNC: "Alexa, abrir fresa" … "xis mais vinte" … "fechar"
Numbers are millimeters. The pendant connects to the cncjs server's socket.io
API (like any other cncjs-pendant-*), sends Grbl $J= jog commands and
exposes a small HTTPS-tunneled endpoint that your own Alexa developer skill
calls. No cloud service in the middle besides Alexa itself; no skill-store
publication needed (a development-mode skill works forever on the Echos of
your Amazon account, for free).
Interaction models for en-US and pt-BR are included, ready to paste.
Safety model
Voice is a lossy input, so the pendant refuses instead of trusting:
- Only
$J=jog commands are ever sent — cancellable instantly, no parser state pollution. Never rawG0/G1. - Per-command travel limits (default: 50 mm on X/Y, 10 mm on Z). Asking for 200 mm gets a spoken refusal, not a move.
- Jogs are refused unless the controller is
Idle/Jogand the cncjs workflow is idle — a running job can never be disturbed. Alarmis reported, never auto-unlocked by voice.- Z uses a slower feed rate than X/Y (defaults: F300 vs F1000).
- "halt" / "para" (and exiting the skill) send Grbl jog-cancel (
0x85). - Every request is cryptographically verified as coming from Alexa
(certificate + timestamp) and, with
--skill-id, from your skill only.
Install
npm install -g cncjs-pendant-alexaRun it on the same host as the cncjs server (it reads the secret from the
server's ~/.cncrc to authenticate, exactly like the other community
pendants):
cncjs-pendant-alexa --port /dev/ttyUSB0 --skill-id amzn1.ask.skill.xxxxOptions: --baudrate 115200, --cncjs-url ws://127.0.0.1:8000,
--http-port 8977, --http-path /alexa, --secret-file /home/cnc/.cncrc,
--max-xy 50 --max-z 10 --feed-xy 1000 --feed-z 300,
--controller-type Grbl.
Sanity check (connects, prints machine state as JSON, exits):
cncjs-pendant-alexa --port /dev/ttyUSB0 --checkSet up the Alexa skill (one time, ~15 min, free)
HTTPS tunnel — Alexa must reach your endpoint over public HTTPS with a valid certificate. Easiest free option: ngrok with the one free static domain every account gets (
ngrok http 8977 --url=yourname.ngrok-free.app). Alternatives: Cloudflare Tunnel (if you own a domain) or Tailscale Funnel. Seeexamples/systemd/alexa-tunnel-ngrok.service.Go to the Alexa developer console → Create Skill → name it (e.g. "CNC Pendant") → primary locale English (US) or Portuguese (BR) → type Custom → host Provision your own.
In Build → Interaction Model → JSON Editor, paste
models/en-US.jsonormodels/pt-BR.json(add the other locale under Language Settings if you want both) → Save Model → Build Model.In Build → Endpoint, choose HTTPS, set the default region to
https://yourname.ngrok-free.app/alexa, and pick the SSL certificate type that matches your host — this choice matters and the errors it causes are silent:- Behind Cloudflare (or any host whose certificate covers your
subdomain via a wildcard like
*.example.com): pick "My development endpoint is a sub-domain of a domain that has a wildcard certificate" (Wildcard). - Only if the certificate names your exact hostname: "...has a certificate
from a trusted certificate authority" (
Trusted).
With the wrong type, Alexa rejects the TLS handshake before any request reaches you, and the simulator only says "endpoint error". The skill invocation API is the one tool that reports the real reason (e.g. "Certificate for host contains wildcard").
- Behind Cloudflare (or any host whose certificate covers your
subdomain via a wildcard like
Copy Your Skill ID (top of the Endpoint page) and pass it to the pendant via
--skill-id.In Test, enable testing in Development. The skill is now live on every Echo logged into your account — no certification, no publication.
Run as a service
Copy the units from examples/systemd/, edit port/skill-id/domain:
sudo cp examples/systemd/*.service /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable --now cncjs-pendant-alexa alexa-tunnel-ngrokGET /healthz on the HTTP port reports the live machine state for monitoring.
Voice reference
The default invocation name is "mill" (pt-BR: "fresa") — change the
invocationName in the model JSON to whatever you prefer before pasting it. Every command
works one-shot ("Alexa, ask my mill x plus 20") or inside CNC mode ("Alexa, open
c. n. c.", then bare commands). While CNC mode is open, unrelated phrases get
a spoken reminder that Alexa is in CNC mode and how to leave; Alexa closes an
idle session on its own after a few seconds of silence (platform limit — a
custom skill cannot hold the microphone open indefinitely).
| Intent | en-US | pt-BR | |---|---|---| | Move (relative) | "x plus 20", "move y minus 5" | "xis mais vinte", "mover y menos cinco" | | Go to (absolute, 1-3 axes) | "position x 130 y 100 z 5", "go to x 50" | "posição x 130 y 100 z 5", "vai para x 50" | | Cancel jog | "halt", "stop moving" | "para", "pare" | | Position | "where are you", "position" | "onde está", "posição" | | Help | "help" | "ajuda" | | Exit CNC mode | "close", "exit cnc mode" | "fechar", "sair do modo cnc" |
Absolute moves use work coordinates and the same per-axis travel limits, measured from the current position.
Development
npm test # unit tests (jog math, state gating, slot parsing)
node bin/cncjs-pendant-alexa --port /dev/ttyUSB0 --no-verify # local testing--no-verify disables Alexa signature verification so you can curl synthetic
request envelopes at the endpoint. Never expose an unverified endpoint.
License
MIT
