Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Project Management with acctl

acctl is the command-line tool for managing AutoCore projects. It handles project creation, deployment, monitoring, and sending commands to the server and its modules.

Configuration

acctl reads server connection settings from acctl.toml in the project directory (created by acctl clone or acctl set-target), falling back to ~/.acctl.toml for global defaults.

[server]
host = "192.168.1.100"
port = 11969

[build]
release = true

Global flags --host and --port override all config files for a single invocation:

acctl --host 192.168.1.200 status

acctl Command Reference

Project Creation

CommandDescription
acctl new <name>Create a new project from the standard template (Rust control program + React web UI)
acctl clone <host> [project] [-P port] [-d dir]Clone a project from a remote server
acctl clone <host> --listList available projects on a server
acctl new my_machine
acctl clone 192.168.1.100 my_machine
acctl clone 192.168.1.100 --list

Project Inspection

CommandDescription
acctl infoShow a human-readable project summary (modules, variables, control program, www status)
acctl validateCheck project.json for errors (syntax, types, duplicate variables, broken links)
acctl statusShow server status, control program state, and project list (requires server connection)
acctl info         # Local — reads project.json, no server needed

Offline Code Generation

The autocore_server executable can generate the gm.rs and results.ts files directly without needing to start the full system (useful for CI/CD or development machines lacking physical hardware like EtherCAT).

# Generate gm.rs and results.ts offline
cargo run --bin autocore_server -- --generate /path/to/project.json

This bypasses the background servelets and exits immediately with code 0 on success. acctl validate # Local — checks for errors before deploying acctl status # Remote — queries the running server


`acctl validate` checks:
- JSON syntax
- Required fields on variables (`type`)
- Valid type values (`f64`, `bool`, `u64`, etc.)
- Duplicate variable names
- Variable `link` targets reference configured module domains

#### Server Configuration

| Command | Description |
|---|---|
| `acctl set-target <host> [--port PORT]` | Save the server address to `acctl.toml` |
| `acctl switch <project> [--restart]` | Switch the active project on the server |

#### Deployment

| Command | Flags | Description |
|---|---|---|
| `acctl push project` | `--restart` | Upload project.json to the server |
| `acctl push www` | `--no-build`, `--source` | Build (`npm run build`) and upload web HMI. `--no-build` skips the build. `--source` pushes full `www/` instead of `www/dist/`. |
| `acctl push control` | `--start`, `--no-build`, `--source`, `--force` | Build (`cargo build`) and upload the control binary. `--start` starts it after upload. `--source` pushes full source for remote build. `--force` skips project.json sync check. |
| `acctl push doc` | `--no-build` | Build (`acctl doc build`) and upload the generated documentation. `--no-build` uploads an existing `doc/book/` without rebuilding (fails if missing). |
| `acctl pull` | `--extract` | Download the active project as a zip |
| `acctl upload <file>` | `--dest PATH` | Upload an arbitrary file to the project directory (default: `lib/<filename>`) |

```bash
# Typical deploy workflow
acctl push project
acctl push www
acctl push control --start

# Or individually with options
acctl push www --no-build        # Skip npm build, push existing dist/
acctl push control --no-build    # Skip cargo build, push existing binary

Control Program Lifecycle

CommandDescription
acctl control startStart the control program
acctl control stopStop the control program
acctl control restartRestart the control program
acctl control statusShow control program state and PID

Monitoring

CommandDescription
acctl statusServer status, control program state, project list
acctl logsShow recent control program log output
acctl logs --followStream logs in real time (colorized by level)

Log levels are colorized: ERROR (red), WARN (yellow), INFO (green), DEBUG (blue), TRACE (dimmed).

Code Generation and Sync

CommandDescription
acctl codegenRegenerate control/src/gm.rs from the server’s project.json (shared memory bindings). Requires a running server.
acctl codegen-tags [--force]Regenerate www/src/AutoCoreTags.ts from the local project.json. Pure local operation — no server connection needed.
acctl syncCompare local vs server project.json interactively. Options: pull, push, or skip per-section. Auto-runs codegen after sync.
acctl diff(Planned) Show what would change on push

After adding or removing variables in project.json, always run acctl codegen to update the Rust shared memory bindings before rebuilding the control program.

acctl codegen-tags — web UI tag generation

Each variable in project.json supports an optional boolean field ux. When "ux": true, acctl codegen-tags emits a record for that variable into the generated block of www/src/AutoCoreTags.ts, giving the React web UI a typed handle (tagName, fqdn, valueType) for subscriptions and controls. Variables without ux: true are ignored.

"variables": {
  "lift_axis_position": { "type": "f64", "ux": true,  "description": "Lift axis position (mm)" },
  "internal_watchdog":  { "type": "u32", "ux": false, "description": "Never shown in HMI" },
  "req_start_auto":     { "type": "bool", "ux": true }
}

Type mapping from project.json to TypeScript’s valueType:

project.json typeTS valueType
bool"boolean"
u8u64, i8i64, f32, f64"number"
string"string"
anything else(warns and skips)

Tag names are derived from the variable name by snake_case → camelCase conversion (lift_axis_positionliftAxisPosition). The FQDN is always gm.<variable_name>.

Output file layout

The generated file contains two arrays combined into the exported acTagSpec:

// autocore-codegen:generated-start
// DO NOT EDIT: this block is regenerated by `acctl codegen-tags`.
export const acTagSpecGenerated = [
    { "tagName": "liftAxisPosition", "fqdn": "gm.lift_axis_position", "valueType": "number" },
    { "tagName": "reqStartAuto",     "fqdn": "gm.req_start_auto",     "valueType": "boolean" },
    // ... one record per variable with ux: true ...
] as const satisfies readonly TagConfig[];
// autocore-codegen:generated-end

// Hand-written tags and per-tag overrides — safe to edit.
export const acTagSpecCustom = [
    { tagName: "liftPosition", fqdn: "gm.lift_axis_position", valueType: "number",
      subscriptionOptions: { sampling_interval_ms: 300 }, scale: "position" },
    // ...
] as const satisfies readonly TagConfig[];

export const acTagSpec = [
    ...acTagSpecGenerated,
    ...acTagSpecCustom,
] as const satisfies readonly TagConfig[];

Put anything that needs subscriptionOptions, scale, or any other TagConfig property into acTagSpecCustom — the generated block only carries the three basic fields. The sentinel comments // autocore-codegen:generated-start and // autocore-codegen:generated-end delimit the replaceable region.

Regeneration behavior

On each run, acctl codegen-tags decides whether to replace only the generated block or rewrite the whole file:

SituationAction
www/src/AutoCoreTags.ts doesn’t existWrite full file from template.
File exists, has both sentinel comments and acTagSpecCustomReplace only the generated block; acTagSpecCustom is preserved.
File exists but missing a sentinel or acTagSpecCustomFull rewrite from template. Old file is saved to AutoCoreTags.ts.bak.
--force is passedFull rewrite regardless. Old file saved to .bak.

A .bak sibling is only ever produced when the tool actually overwrites a hand-edited file — routine in-place updates leave nothing on disk besides the new AutoCoreTags.ts.

Workflow
# Mark variables for the UI in project.json (editor or acctl import-vars)
# Then:
acctl codegen-tags            # → www/src/AutoCoreTags.ts
cd www && npm run dev         # React picks up the updated tag list immediately

Run codegen-tags any time you flip ux on/off or add/rename variables. The React side has no caching — refreshing the dev server or the built app picks up the new list on next load.

Variable Management

CommandDescription
acctl export-vars [--output FILE]Export variables to CSV (default: variables.csv)
acctl import-vars [--input FILE]Import variables from CSV (default: variables.csv)
acctl dedup-varsFind and interactively resolve variables with duplicate hardware links

CSV columns: name, type, link, description, initial.

acctl export-vars --output variables.csv
# Edit in spreadsheet...
acctl import-vars --input variables.csv
acctl dedup-vars   # Check for conflicts

Project Documentation

Every project created by acctl new includes a doc/ directory with an mdBook-based user manual. The acctl doc subcommands build, serve, and keep that manual in sync with project.json and the control program source.

CommandFlagsDescription
acctl doc init--forceScaffold doc/ (book.toml + the five starter Markdown files) in an existing project. Skips files that already exist; --force overwrites. Use this to add the doc directory to projects created before acctl doc support.
acctl doc buildBuild static HTML output at doc/book/. Runs generate-vars and cargo doc automatically.
acctl doc serve--port PORT (default 4444)Serve the book locally with live reload.
acctl doc generate-varsRegenerate doc/src/variables.md from project.json (hardware-linked / bit-mapped / plain tables).
acctl doc cleanRemove doc/book/ and doc/src/rustdoc/.
acctl doc init                     # Scaffold doc/ if the project doesn't have one yet
acctl doc serve                    # http://localhost:4444 with live reload
acctl doc serve --port 8080        # Custom port
acctl doc build                    # One-shot build → doc/book/index.html

New projects created by acctl new already contain a scaffolded doc/, so you only need acctl doc init when retrofitting an older project or when you’ve deleted doc/ and want to start over. The command reads the project name from project.json to populate the book title and introduction page, and never overwrites files by default — safe to run repeatedly.

On first use, if mdbook is not on your PATH, acctl installs it automatically via cargo install mdbook --locked (one-time, ~60s). cargo doc ships with every Rust toolchain, so no additional installation is needed for the Rustdoc section.

Distribution

The output at doc/book/ is a self-contained static site. You have three distribution options:

  1. Push to the serveracctl push doc builds the book and uploads it to the active project on the server. autocore-server automatically serves the active project’s documentation on its documentation port (default 4444, configurable in config.ini):

    http://<server-ip>:4444/
    

    Operators get up-to-date docs as a side effect of deployment — no separate hosting required. When no documentation has been pushed, the port serves a placeholder page explaining how to run acctl push doc. Switching the active project on the server automatically swaps the served docs to the new project’s book.

  2. Zip and sharedoc/book/ is fully self-contained. Zip it, email it, or drop it on a shared drive. Recipients unzip and open index.html directly from the filesystem.

  3. Host elsewhere — Push doc/book/ to any static web host (GitHub Pages, S3, internal nginx, etc.). All links are relative.

Configuring the documentation port

The server reads the doc port from config.ini:

[general]
port = 80          # Main HMI port
doc_port = 4444    # Documentation port (this)

Omit doc_port to use the default of 4444. Set it to a different value if 4444 is already in use on the target.

Note: As of this writing, autocore-server’s HTTP endpoints — including port 4444 — are unauthenticated. If your project documentation contains sensitive information, keep the server on a trusted network until the forthcoming authentication gate ships.

Sending Commands to Modules

CommandDescription
acctl cmd <topic> [args...]Send a command to the server (same as the AutoCore console)

The topic format is domain.command. Arguments are parsed as --key value pairs. Values are auto-detected as numbers, booleans, JSON objects/arrays, or strings.

# System commands
acctl cmd system.get_domains
acctl cmd system.list_modules
acctl cmd system.load_module --name ni
acctl cmd system.new_project --project_name my_machine

# Global Memory (read/write variables)
acctl cmd gm.read --name motor_speed
acctl cmd gm.write --name motor_speed_setpoint --value 1500

# Module commands (NI example)
acctl cmd ni.status
acctl cmd ni.describe
acctl cmd ni.add_channel --task AnalogInput --name ai0 --physical_channel Dev1/ai0 --type voltage
acctl cmd ni.save_config --generate_variables true

# Any module that implements CommandRegistry
acctl cmd modbus.status
acctl cmd labelit.camera_start --ip 192.168.1.50

Working with Multiple Projects

Each AutoCore server can host multiple projects, but only one is active at a time.

acctl status                                    # See all projects and which is active
acctl switch other_project --restart            # Switch to a different project
acctl cmd system.new_project --project_name new_machine  # Create a new project on the server

Deploying to a Remote Server

# 1. Set the target server (saved to acctl.toml)
acctl set-target 192.168.1.100

# 2. Verify the connection
acctl status

# 3. Validate before deploying
acctl validate

# 4. Deploy
acctl push project
acctl push www
acctl push control --start

# 5. Monitor remotely
acctl logs --follow

Importing and Exporting Variables

For large projects, manage variables in a spreadsheet and import them:

acctl export-vars --output variables.csv
# Edit the CSV in your spreadsheet application...
acctl import-vars --input variables.csv
acctl dedup-vars   # Resolve any duplicate links

The CSV format has these columns: name, type, link, description, initial.

Writing Project Documentation

The project’s doc/ directory is an mdBook — the same tool used for this manual. Source files live in doc/src/ as Markdown; the table of contents is doc/src/SUMMARY.md.

Default layout (created by acctl new, or by acctl doc init on an existing project):

doc/
├── book.toml              # mdBook configuration
└── src/
    ├── SUMMARY.md         # Table of contents
    ├── introduction.md    # Edit this — your project overview
    ├── variables.md       # Auto-generated — do not edit
    └── control_api.md     # Links to the Rustdoc section

Retrofitting older projects. If your project was created before acctl doc support and doc/book.toml doesn’t exist, run acctl doc init from the project root. It scaffolds the same five files that acctl new would have produced, pulling the project name from project.json for the book title. Existing files are left untouched; pass --force to overwrite.

What Gets Auto-Generated

Two parts of the book are regenerated every time you run acctl doc build or acctl doc serve — do not edit them by hand:

  • doc/src/variables.md — a grouped FQDN table of every entry in project.json’s variables map. Three sections are emitted when non-empty: Hardware-Linked (entries with a link field), Bit-Mapped (entries with source + bit), and Other. Columns include FQDN, type, description, and the relevant linkage fields.
  • doc/src/rustdoc/ — a copy of cargo doc --no-deps output from control/. The default control_api.md chapter links into rustdoc/index.html. Doc comments (///) in your control program source become a browsable API reference.

Typical Authoring Workflow

# Start the live-reload server while you write
acctl doc serve

# In another shell, edit doc/src/introduction.md and any other chapters
# Add new chapters by creating new .md files and listing them in SUMMARY.md

# Once happy, produce a static build to hand off
acctl doc build
# → doc/book/index.html

Because generate-vars and cargo doc run on every build, changes to project.json variables or doc comments in control/ appear in the book without any extra step.

Distribution

doc/book/ is a standalone static site — no runtime dependencies, all links relative. Typical distribution options:

  • Zip doc/book/ and email or share the archive; recipients unzip and open index.html directly.
  • Push doc/book/ to any static web host (GitHub Pages, S3, an internal nginx, etc.).
  • Commit doc/book/ to a docs branch for versioned online access.

Add doc/book/ and doc/src/rustdoc/ to your .gitignore if you prefer to keep only sources in version control — both are fully reproducible from the sources plus project.json and control/.