Skip to main content

Rail Deck is being prepared for an invitation-only Alpha. Check current availability

Developer documentation

Train and accessory commands

Submit locomotive, function, accessory and emergency Stop requests and recover original accessory outcomes.

Source 0.1.0 Private source package

How the calls fit together

Require current authority and an explicit operator action. Keep original command identity; timeout or disconnect never authorises an automatic retry.

JavaScript examples

Supply your configured client. Each call awaits a decoded result; errors pass to your caller. These identifiers and values are fictional. Use selected development records and review every change before running it. Opening this page sends no API requests.

See the complete TypeScript workflow · Explore the Node starter

liveCommands.recoverAccessoryCommand

Asks about an original accessory command without sending it again.

const result = await client.liveCommands.recoverAccessoryCommand(
  "1",
  "21",
  "11111111-1111-4111-8111-111111111111",
  {
    "layoutId": "18"
  },
  {}
);
TypeScript parameters and return type
accountId · required
RailDeckIdentifier

Account which owns the saved command.

controllerId · required
RailDeckIdentifier

Original controller, not replacement wiring.

commandId · required
RailDeckIdentifier

Previously accepted command to recover.

input · required
RecoverAccessoryCommandInput

Layout scope for current operator authorisation.

options · optional
RailDeckRequestControlOptions

Caller-owned cancellation and deadline; interruption never means rollback.

Returns Promise<AccessoryCommandRecoveryResponse>.

Example evidence: Retained SDK transport fixture.

liveCommands.setLocomotiveSpeed

Sets a locomotive speed using user-facing direction.

const result = await client.liveCommands.setLocomotiveSpeed(
  "account-1",
  "controller-1",
  {
    "layoutId": "layout-1",
    "locomotiveId": "loco-1",
    "speedPercent": 35,
    "direction": "forward",
    "trainFormationId": "formation-1"
  }
);
TypeScript parameters and return type
accountId · required
RailDeckIdentifier

Account that owns the controller.

controllerId · required
RailDeckIdentifier

Controller that should receive the command.

input · required
SetLocomotiveSpeedInput

Layout, locomotive, speed, direction, and optional expiry.

Returns Promise<RailDeckLiveCommandResponse>.

Example evidence: Retained SDK transport fixture.

liveCommands.setLocomotiveFunction

Triggers or toggles a locomotive function.

const result = await client.liveCommands.setLocomotiveFunction(
  "account-1",
  "controller-1",
  {
    "layoutId": "layout-1",
    "locomotiveId": "loco-1",
    "functionNumber": 2,
    "active": true,
    "momentary": true
  }
);
TypeScript parameters and return type
accountId · required
RailDeckIdentifier

Account that owns the controller.

controllerId · required
RailDeckIdentifier

Controller that should receive the command.

input · required
TriggerLocomotiveFunctionInput

Layout, locomotive, function number, active state, and momentary mode.

Returns Promise<RailDeckLiveCommandResponse>.

Example evidence: SDK fixture assertion: packages/frontend-sdk/src/index.test.ts.

liveCommands.setAccessoryState

Sets one accessory state through the live command path.

const result = await client.liveCommands.setAccessoryState(
  "1",
  "21",
  {
    "layoutId": "18",
    "accessoryId": "194",
    "state": "thrown",
    "configurationRevision": 3,
    "expiresInMs": 2000,
    "commandId": "6ab90f92-1111-4111-8111-000000000001",
    "priority": "high"
  },
  {}
);
TypeScript parameters and return type
accountId · required
RailDeckIdentifier

Account that owns the controller.

controllerId · required
RailDeckIdentifier

Controller that should receive the command.

input · required
SetAccessoryStateInput

Layout, saved accessory, destination, optional reviewed revision and priority.

options · optional
RailDeckRequestControlOptions

Caller-owned cancellation and deadline, without automatic retry.

Returns Promise<RailDeckLiveCommandResponse>.

Example evidence: Retained SDK transport fixture.

liveCommands.emergencyStop

Sends an emergency track-power-off command through the live path.

const result = await client.liveCommands.emergencyStop(
  "account-1",
  "controller-1",
  "layout-1",
  undefined
);
TypeScript parameters and return type
accountId · required
RailDeckIdentifier

Account that owns the controller.

controllerId · required
RailDeckIdentifier

Controller that should receive the command.

layoutId · required
RailDeckIdentifier

Layout being controlled.

track · optional
string

Track scope, usually `main`.

Returns Promise<RailDeckLiveCommandResponse>.

Example evidence: SDK fixture assertion: packages/frontend-sdk/src/index.test.ts.

Download all TypeScript method examples

JavaScript calls and TypeScript downloads are checked through the real SDK using local response fixtures. This verifies the calls and decoding for those fixtures.

Handle errors and uncertain outcomes

Choose another feature

The complete TypeScript workflow

Follow how the calls fit together, including the review and recovery steps. Supply your configured client and explicitly selected development records. Importing the download performs no requests; mutations are never retried automatically.

import type { RailDeckDirectIntegrationClient as Client } from '@raildeck/frontend-sdk/direct-integration';

/**
 * Send an explicitly requested emergency Stop without delaying it for another read.
 * @param client - Configured client; the caller owns current authority.
 * @param accountId - Authorised account for this workflow.
 * @param layoutId - Explicitly selected layout within the account.
 * @param controllerId - Explicitly selected command station.
 * @param track - Selected track output; this helper only requests power off.
 * @returns The SDK command response; physical Stop still needs its own evidence.
 */
export async function stopSelectedTrack(
  client: Client,
  accountId: string,
  layoutId: string,
  controllerId: string,
  track: string,
) {
  return client.liveCommands.emergencyStop(accountId, controllerId, layoutId, track);
}

/**
 * Recover the original accessory command and read the current layout observation.
 * @param client - Configured client; the caller owns current authority.
 * @param accountId - Authorised account for this workflow.
 * @param layoutId - Explicitly selected layout within the account.
 * @param controllerId - Explicitly selected command station.
 * @param commandId - Original command identity; never replace it to retry.
 * @param signal - Caller-owned cancellation signal.
 * @returns Both observations without submitting a replacement command or replaying movement.
 */
export async function recoverAccessoryOutcome(
  client: Client,
  accountId: string,
  layoutId: string,
  controllerId: string,
  commandId: string,
  signal: AbortSignal,
) {
  const options = { signal, timeoutMs: 15_000 };
  const outcome = await client.liveCommands.recoverAccessoryCommand(
    accountId, controllerId, commandId, { layoutId }, options,
  );
  const snapshot = await client.currentState.getLayoutSnapshot(accountId, layoutId, options);
  return { outcome, snapshot };
}
Download TypeScript example

Information reviewed .