Robot Manager Beta

not connected not logged in

Log in

Login is POST /api/User/Token (form-urlencoded); every call after that carries Authorization: Bearer. The token stays in this browser tab, the password is not stored. A cloud token is valid for 60 minutes.
Operate

Vision
Live

Fleet

Log in to see the robots

Robots

Where this comes from
Busy, maintenance, pause and firmware are the columns of GET /api/SAODF/, as in the top bar. Offline is an open ROBOT_IS_OFFLINE alarm, since the time it appeared (UTC, as in the alarm list; the real outage can be a few minutes earlier). Alarms counts the other open alarms (NEW and ACKNOWLEDGED) of a robot, the maintenance alarm included. Enter in the search opens the robot when one is left; Esc clears it. Queues is GET /api/queue/ (API 0.0.90): every robot whose job queue has an open job, a runner, a reason it waits or a halt. Active is a robot that is executing a job: one in flight in its queue, or busy (SaodfIsActive).

Queues –

Every job queue in use in the fleet, running first.

Open alarms

Newest first, for the robots in the fleet selection.
RobotAlarmSince (UTC)
nothing loaded yet

Live camera

only the robot selected at the top; switching robots switches the picture
s off

Vision check vision unknown

ROI: the one of the model
TimeJobCheckSlotModeVerdictScoreReason
nothing loaded yet

Robot queue

-- log in first --
PosJobCommandStatusPrioHeld until (UTC)Details
nothing loaded yet

Robot

Movementmoves
Manual movementmoves
Dustcapsmoves
Cords and ports
From Ports… an inspect, a DC, an IC, a CC or a test makes the robot move; the other five only read or write the database.

Robot details

Create campaign

Tap ✕ to remove a command; tap the text to edit it. Jobs run in this order. Load .txt… (or drop a .txt on this card): one command per line; empty lines and lines that start with # are skipped.

Build a line

The ports of the selected robot are loaded into the port picker.

One job, starts now, not prioritized. Full adds more jobs, an example, a schedule or priority.

Random test

Ports at random over the whole rack, from the ports that are available now: the same slot, cord and dustcap selection as Create campaign, with the open jobs of the robot counted as done. The commands join the list; nothing is sent before Create campaign.

Options

Alarms

-- log in first --
IdStateSeverityAppeared (UTC)WhatDetailRef
nothing loaded yet

Campaigns and status

IdNameCreatedScheduled (UTC)JobsStatusPrio
nothing loaded yet

OTDR traces

nothing downloaded yet
TestIdPortStartedEndedStatusFileTrace
nothing loaded yet
How it works · error codes
The trace comes through the API as bytes, not as a presigned URL, and the call carries the bearer token — so the file is fetched and handed to the browser as a download; it lands in your normal download folder. 409 means the test exists but has no trace yet (Pending, or Failed), 404 that there is no such test or the key points at an object that is gone, 502 that S3 refused and 503 that no bucket is configured (local mode). With a port filled in the list comes from GET /api/TestResult/{port}/OTDR, which filters on TEST_TYPE = 1: measurements from before 2026-09-01 carry NULL there and stay out of it — leave the port empty to see those too.

Calibration

Home positions, offsets, parameters and the automatic X/Y/Z run with the calibration plates. It writes the database; Sync to robot loads it into the firmware. The automatic run makes the robot move.

OTA firmware update

idle
unknown

Network (IP, subnet, gateway, MAC, server)

unknown
idle
fill in only what changes; an empty field keeps its value on the robot
How a change works
Needs firmware 5.0.5.0 or newer. The API checks every field (422) and refuses an IP or MAC that another robot already has (409). The robot checks again, also that its core stays in the subnet, and refuses without changing anything (the reason is on its status topic, in CloudWatch /gigacom/robots/{id}). It restarts on the new settings; if it cannot reach its core within 5 minutes it puts the old ones back and restarts again, so a typo costs about six minutes offline. Only the IP comes back over HTTP, so only an IP change can be followed here. Server is the core the robot connects to (firmware 5.0.6.33 or newer; kept on the robot next to its IP). The robot must be known there, as a client device of that core; otherwise the same 5 minutes bring it back to the old server. The server it runs on is in every answer of Ask robot for network (broker, in CloudWatch).

Camera

unknown
How it works
Connect writes rtsp://{Camera IP}:5005/routecam into CameraStreamURL, the address into SAODF_CAMERA_IP and CameraId, and the IVS stage saodf-{id}-routecam into SAODF_IVS_STAGE_ARN. The robot keeps the stage it has (existing), a stage of that name that is not in the database yet is taken over (adopted), else one is made (created); safe to repeat. The cloud cannot reach the camera, so the address is not checked here: press Watch on Operate. That works without a deployment once the robot is a client device of its core (CamPublisher 1.0.5 or newer), and the core puts the camera on 720p at the first start. 409 means the address or the stage belongs to another robot; 403 needs an admin profile.

Slot data (Excel)

nothing exported yet the full slot data of the selected robot, in the shape the import reads back

Import

no file
How it works · error codes
Export and import are two halves of one round trip: export, edit in Excel, import back. 404 ROBOT_NOT_PROVISIONED means there is no StationMaster row for this robot, 422 WORKBOOK_FORMAT that the sheets are not what the parser expects, and 422 SHAPE_MISMATCH that the file does not fit the provisioned shape of this robot. FILE_LARGER_THAN_SYSTEM means the file has more doors than the robot: with allow_grow the import makes the robot that size. The robot gets its extra doors in the sync from firmware 5.0.6.0 on.

Configuration

Robot (SAODF)

-- log in first --
nothing loaded yet

Storage thresholds (cord alarms)

-- log in first --
ModuleOperator (PLC)Stored / slotsRow ARow BAppliesAlarm now
nothing loaded yet
How thresholds work

Storages: 4 or 8 per door, and their operator

nothing loaded yet
StorageDoorSlotsOperatorStored / freeThresholdAlarm now
nothing loaded yet
How storages work
A storage module (AS1, AS2, BS1, BS2 at door 1) is two rows of 20 storage slots. With 4 storages per door the module is the storage; with 8 each row is a storage of its own (AS1-1 the top row, AS1-2 the one below) with its own cord alarm, its own threshold entry (row A, row B above) and its own operator. The choice is per door (PATCH /api/SAODF/{id}/doors/{door}, the four SAODF_STORAGE columns of the door together); 4 to 8 always goes, 8 to 4 only when both rows of every module have the same operator. Operator gives the storage to an operator (PUT /api/SAODF/{id}/storages/{storage}/operator: every slot gets its PLC id as SlotType); a storage with cords in it keeps its operator until they are out. Nothing goes to the robot: the firmware knows slots, not storages or operators. Both need an admin profile. The cord alarms are recomputed right after.

Site settings (dbo.WinServiceSettings)

One row for the whole site; the columns are those of this database. In bold: the four this API reads (rounds per campaign and the minutes between two rounds, each for a normal and a priority campaign); the rest is read by the LMU app.
nothing loaded yet

Operator colours (port map)

The colour of the IC cords of each operator on the port map; the CCs stay green. Stored in Operators.OPERATOR_COLOR and saved as soon as you pick one. Default gives the operator a colour of the page's own palette.
nothing loaded yet

Users

IdNameProfileDetail 1
nothing loaded yet

New user

How users work
A user logs in on this page and on every call to the API (POST /api/User/Token). Creating and deleting needs a login with an admin profile (403 otherwise); the profile decides what the new user may do. The password is stored hashed, so a user made here cannot log in to the old LMU app, and the users of that app cannot log in here until they get a new password (PATCH /api/User/{id}). A user with cords or alarms on their name cannot be deleted (409).

Free request

Useful paths: /api/version, /api/Port/1?limit=20, /api/Active/Operators, /api/TestProfile/, /api/Configuration/, /api/Alarm/?limit=20, /docs in a new tab.

Request log

Add cord

-- log in first --
Registers a cord that is already patched: one row in Cords and the occupancy of its slots. The robot does not move, and no sync is needed: the backend chooses every slot of a DC, IC or CC itself and sends the slot numbers in the command, so the firmware never reads the occupancy. Side A decides the type: an ACTIVE_NAME makes an IC, a port makes a CC. Splitter inputs (…_IN) are not offered: an IC goes from a splitter output.

Several cords

One cord per line: side A, then side B. Two columns pasted from Excel work as they are; otherwise separate them with a space, a comma or a semicolon. Each line decides its own type, as above. One confirmation for the whole list; afterwards only the lines that were not registered stay in the box, so you can correct them and go again.

Add splitter

-- log in first --
Adds a 1x64 splitter to this robot as rows in Active: <name>_IN and <name>_1 … _64. Its place is a side, a row (A–D) and a position (1–6); every row gets it as <robot>_<side><row>_<position>. On a one-door robot you pick side A or B, a row and a position, and a place holds one splitter. With more doors you type the place (side of any door, row, position); it is not checked for another splitter yet. Database only, nothing moves. An IC cord then goes from an output with Add cord…. All fields are required; nothing is written when a name, the serial number or the place is already taken.

Hang splitter

-- log in first --
Registers a splitter that is laid in this robot, in three steps; the database only, nothing moves. 1 A new splitter (its …_IN has no cord yet) also gets its input in a normal port, registered together with the blocks. 2 Pick a storage of its operator; a storage with CC cords takes no IC cords. 3 Per block a start port (click a free slot in the storage, or leave it empty for the first free port where it fits), its size (12 or 8) and the output in the start port (12, 24, 44 or 56 for 12; 32 or 64 for 8). From the start port the block runs to the right and the outputs count down, as in the manual. Suggestion fills in the fill scheme. The table shows which output goes into which port, in loading order; the robot takes them in reverse.

1 · Splitter

Add robot

Creates the robot in the database from the MU or MDC template: rack, home positions, parameters, sections, slots and ports. Its id is the next free one. Afterwards it is set up like any robot (calibration, network); the AWS side (certificate, camera) is not part of this. There is no delete yet.

Alarm details

Free text, as in the alarm edit screen of the LMU app; an empty field is cleared. What the API itself uses while the alarm is open stays greyed out until it is closed (hover a grey field for why). API 0.0.78 or later.

Remove cord

-- log in first --
Records a cord that was pulled out by hand: its Cords row becomes REMOVED and its slots are free again (an IC clears its one slot, a CC both). The robot does not move. Refused (409) while a DC, IC or CC of this robot is running, or while a job that has not ended names one of the cord's ports; the message names the job. API 0.0.55 or later.

Dustcap

-- log in first --

Resume queue

-- log in first --

Home axes

-- log in first --
Untick an axis to leave it where it is (firmware 5.0.6.1). R, X and Y only home together with Zg and Zt. With the calibration sensor in the gripper the robot never homes G, also when it is ticked.

Vision check

The picture of the check

Ports and cords

-- log in first --
normal parking storage CC cord (to another port) IC cord (to an operator's Active) disabled: module, row or port not installed waiting in the queue running now (blinks)
How to read the map
From GET /api/Port/{id}, the list that also fills the port pickers. One column per section (the letter of the module in SAODFPORT_DETAIL1), one line per row of consecutive slots, in slot order: so row A 1–20 sits next to row B 21–40. ConnectedSaodfPort is the other end of the live cord: a port of this robot for a CC, an ACTIVE_NAME for an IC. A CC is a green dot; an IC is a ring in the colour of the operator of that Active (GET /api/Active/?unused=false&saodf={id}), grey when the Active is not found. A storage slot has a light tint and a border in the colour of the operator it belongs to: its SlotType in the slot data is that operator's OPERATOR_PLC_ID (GET /api/sync/{id}/preview); it stays grey when it belongs to no operator. The colour of an operator is set under Setup → Configuration → Operator colours. The search box finds an operator name too, on its IC cords and its storage. The map itself is read-only. The panel beside the map describes the selection; what the robot can do on it sits in the bar at the bottom of this window, which stays in view while the map scrolls.
Inspect… works on any port: one INSPECT job, the robot moves the gripper to that slot and stays there with the camera light on (2 minutes). Watch camera shows the live picture of the robot beside the map, the same one as the Live camera card, which gets it back when this window closes. On a normal port with a cord, Disconnect (DC)… creates a campaign with one DC job; on a free normal port, Interconnect (IC)… does the same with IC <port> <operator>. Crossconnect (CC)… makes that port side A and turns on select several: click side B on the map (or Ctrl-click two free normal ports, the first is side A), then Crossconnect (CC)… under the selection creates CC <A> <B>; Swap turns A and B round. A cord with both ends in storage goes into A first and into B once A succeeded. These three and Inspect make the robot move. Remove this cord… only writes the database.
Test runs a VFL test (VF) or an OTDR measurement (OT) on the selected normal port, or on several: tick select several (or Ctrl-click), Shift-click for a range within one section, or search and Select matches. That is one campaign with one job per port, in slot order; with fast the first port of each row gets the plain verb (its full homing gives the axis reference) and the rest VFF/OTF. A test expects a free port with a dustcap: it takes the cap off, puts the probe in and puts the cap back. A port with a cord can be tested, but the page warns first.
Save details writes Detail 2 and 3 of one port with PATCH /api/Port/{robot}/{slot} (up to 50 characters each; empty clears the field). Nothing moves.
Modules… (the button above the map, from GET /api/SAODF/{id}/modules): untick a module that is not installed on this robot. PUT /api/SAODF/{id}/modules/{module} then writes OccupiedSlot = -10000 on its slots; its ports are hatched on the map, no job may use them, and no parking, storage or temporary slot in it is chosen. Tick it to switch it back on. A row or a single port goes the same way from the bar below the map: click a port, then Disable port… or Disable row… (PUT /api/SAODF/{id}/ports, PUT /api/SAODF/{id}/rows/{first slot}); with several ports selected, Disable N ports…. A hatched port has Enable port… and Enable row…. What holds a cord or a temporary dustcap slot cannot be switched off (hover it for why), and switching needs an admin user.

Next cord per operator

-- log in first --
How to read this table
Which stored cord an interconnect (IC) takes next, per rack section: the same choice an IC job makes. Grouped by rack section; one row per operator that has storage slots in it. Used for IC into names the sections whose IC takes that cord: its own, and the paired one (1↔2, 3↔4) when the pair has none of this operator's cords itself. Read-only.
OperatorStorage modulesNext cordCord id LeftUsed for IC into
nothing loaded yet

Calibration

no changes to sync
Everything here writes the database only. The robot uses it after Sync to robot (POST /api/sync/{id}). Offsets are relative: applying one twice moves twice.

Home positions · absolute, mm

homePosX1 is used by rack sections 1-4, X2 by 5-8, X3 by 9 and up. At most 4 decimals.
Saves write the database; the robot uses them after the sync.