Table of Contents
Controlling SECS/GEM Messages via AMQP Routing Keys
This document describes how to use AMQP 1.0 routing keys (tag addresses) to send SECS/GEM commands to equipment and monitor responses. All communication uses an AMQP 1.0 broker; you publish values to request tags and subscribe to response/variable tags to observe results.
Throughout this document, <toolname> refers to the name assigned to the equipment controller (e.g. e300host). All routing keys are lower-case and dot-separated.
General Concepts
Request/Response Pattern
Most SECS/GEM operations follow a common three-step pattern:
- Set parameters — publish values to one or more parameter tags (e.g. an SVID list, a terminal ID, text, etc.)
- Trigger — publish
1to the correspondingsendmessagetag - Monitor — subscribe to the
responsestatustag and/or the output variable tags to observe results
The responsestatus tag will change to 0 on success. You can seed it with a non-zero value (e.g. 99) before triggering so that the transition to 0 is unambiguous.
Data Format Summary
| SECS Type | Type Code | Description | Example Value |
|---|---|---|---|
| Binary (B) | 10 | Raw bytes | 0x01 (single byte) |
| Boolean | 11 | true/false, yes/no, or 1/0 | true |
| ASCII (A) | 20 | Plain text string | Hello World |
| I1 | 30 | 1-byte signed integer | 42 |
| I2 | 31 | 2-byte signed integer | 1024 |
| I4 | 32 | 4-byte signed integer | -5000 |
| I8 | 34 | 8-byte signed integer | 123456789 |
| F8 | 40 | 8-byte floating point | 3.14159 |
| F4 | 44 | 4-byte floating point | 1.23 |
| U1 | 50 | 1-byte unsigned integer | 255 |
| U2 | 51 | 2-byte unsigned integer | 65535 |
| U4 | 52 | 4-byte unsigned integer | 30508 |
| U8 | 54 | 8-byte unsigned integer | 30508 |
| List (L) | 00 | Ordered list of items | See List Format |
Data Formats
Simple Types
Simple (scalar) tags accept plain string values published directly to the routing key. The equipment knows the expected SECS type for each tag and will interpret the string accordingly.
Examples:
- Publishing an integer: just send the numeric string
30508
- Publishing a text string:
Hello from the operator console
- Publishing a binary byte value of 1 (as a raw byte):
\x01
No JSON wrapper is required for simple types.
List Format (SecsFormat00)
List-type tags (such as SVID lists) require a JSON object with a “values” array. Do not send a bare JSON array — it must be wrapped in an object.
All items the same type
If every item in the list is the same SECS type, include a “type” field:
{"values": [30503, 30508], "type": 54}
This produces a list of two U8 (type 54) values. If “type” is omitted, each element defaults to ASCII (type 20) strings.
All items as strings (default)
{"values": ["recipe1", "recipe2", "recipe3"]}
Without a “type” field and with simple string elements, each item becomes a SecsFormat20 (ASCII) value.
Mixed types
When list elements have different types, use the value/type object form for each element:
{"values": [ {"value": "1.2", "type": 34}, {"value": "Test", "type": 20}, {"value": "15", "type": 54} ]}
Empty list
{"values": []}
Nested lists
A list can contain sub-lists by setting the type of an element to 0 (list) and providing a JSON string as the value:
{"values": [ {"value": "{\"values\": [\"a\", \"b\"], \"type\": 20}", "type": 0}, {"value": "standalone", "type": 20} ]}
DVVAL (Data Variable Value) Format - Tool Deployment Only
For report data variables, the format uses a “values” array of “dvid”/“dvval” pairs:
{"values": [ {"dvid": "WaferCount", "dvval": "15"}, {"dvid": "23456", "dvval": "Hello World"} ]}
Operations Reference
Status Variable Request (List)
Request multiple status variable values in a single S1F3 transaction.
| Direction | Routing Key | Format | Description |
|---|---|---|---|
| Publish | <toolname>.svrequest.svidlist | JSON list (see List Format) | List of SVIDs to request |
| Publish | <toolname>.svrequest.responsestatus | Plain integer | Seed with 99 before triggering |
| Publish | <toolname>.svrequest.sendmessage | 1 | Triggers the S1F3 request |
| Subscribe | <toolname>.svrequest.responsestatus | Plain integer | Becomes 0 on success |
| Subscribe | <toolname>.variables.vid.<varname> | Depends on variable | Individual variable values update |
Example — request CLOCK (SVID 30508) and ControlState (SVID 30503):
- Subscribe to
e300host.svrequest.responsestatus - Subscribe to
e300host.variables.vid.clock - Subscribe to
e300host.variables.vid.controlstate - Publish
99toe300host.svrequest.responsestatus - Publish
{“values”: [30503, 30508], “type”: 54}toe300host.svrequest.svidlist - Publish
1toe300host.svrequest.sendmessage - Wait for
e300host.svrequest.responsestatusto become0 - Read the updated values from
e300host.variables.vid.clockande300host.variables.vid.controlstate
Status Variable Request (Single)
Request a single status variable value.
| Direction | Routing Key | Format | Description |
|---|---|---|---|
| Publish | <toolname>.svrequestone.svid | Plain integer | The SVID to request (e.g. 30508 for CLOCK) |
| Publish | <toolname>.svrequestone.responsestatus | Plain integer | Seed with 99 before triggering |
| Publish | <toolname>.svrequestone.sendmessage | 1 | Triggers the request |
| Subscribe | <toolname>.svrequestone.responsestatus | Plain integer | Becomes 0 on success |
| Subscribe | <toolname>.variables.vid.<varname> | Depends on variable | The variable value updates |
Example — request CLOCK only:
- Subscribe to
e300host.svrequestone.responsestatus - Subscribe to
e300host.variables.vid.clock - Publish
99toe300host.svrequestone.responsestatus - Publish
30508toe300host.svrequestone.svid - Publish
1toe300host.svrequestone.sendmessage - Wait for
e300host.svrequestone.responsestatusto become0 - Read the updated value from
e300host.variables.vid.clock
Terminal Display
Send a text message to the equipment's terminal display (S10F3).
| Direction | Routing Key | Format | Description |
|---|---|---|---|
| Publish | <toolname>.terminaldisplay.tid | Binary byte | Terminal ID (e.g. byte value 0x01 for terminal 1) |
| Publish | <toolname>.terminaldisplay.text | Plain string | The text to display |
| Publish | <toolname>.terminaldisplay.responsestatus | Plain integer | Seed with 99 before triggering |
| Publish | <toolname>.terminaldisplay.sendmessage | 1 | Triggers the S10F3 message |
| Subscribe | <toolname>.terminaldisplay.responsestatus | Plain integer | Becomes 0 on success |
Example — display a message on terminal 1:
- Subscribe to
e300host.terminaldisplay.responsestatus - Publish
99toe300host.terminaldisplay.responsestatus - Publish byte value
0x01toe300host.terminaldisplay.tid - Publish
Hello from the operatortoe300host.terminaldisplay.text - Publish
1toe300host.terminaldisplay.sendmessage - Wait for
e300host.terminaldisplay.responsestatusto become0
Monitoring Output Tags
Variable Tags
Equipment variables are published to routing keys under <toolname>.variables.vid.<varname>, where <varname> is the lower-case variable name defined in the equipment model (e.g. clock, controlstate).
Subscribe to these tags to receive updated values whenever the equipment reports them — either in response to an SV request or as part of an event report.
Event Reports
When the equipment sends an event report, it is encoded as JSON and published to the event's routing key. The format is:
{"EventName": [ {"ReportName": [ {"GasFlow": "1.2", "type": 34}, {"WaferCount": "15", "type": 54} ], "rptid": 109} ], "ceid": 1003, "timestamp": "2025-03-22 14:29:13.306"}
Each report within the event contains a list of named values with their SECS type codes.
Alarm Notifications
Alarm events are published as JSON:
{"alid": 1002, "altx": "Temperature Alarm", "alcd": 2, "action": "set", "timestamp": "2025-03-22 14:29:13.306"}
The “action” field is either “set” (alarm raised) or “clear” (alarm cleared).
Trace Data
Trace data reports follow a similar structure to event reports:
{"TraceName": [ {"GasFlow": "1.2", "type": 34}, {"Temperature": "350.5", "type": 40} ], "trid": 5, "timestamp": "2025-03-22 14:30:00.000"}
"Devices" Tags
Tags that are not part of the SECS/GEM protocol (e.g. devices.utilityservers_servers.variable) use plain string publish/subscribe with no special formatting. Publish a string value and any subscriber on that routing key will receive it directly.
Troubleshooting
| Symptom | Likely Cause | Solution |
|---|---|---|
responsestatus never changes | Subscriber created after publish (queue did not exist) | Always create subscribers before publishing. The AMQP queue must exist to receive messages. |
JSONException: A JSONObject text must begin with { | Sent a bare JSON array [1,2,3] to a list tag | Wrap in an object: {“values”: [1,2,3]} |
| Variable tag stays empty after successful response | Wrong SVID number, or variable name mismatch | Verify the SVID is correct for your equipment model and that you are subscribing to the right <varname> |
| Terminal display returns non-zero status | Equipment rejected the message (e.g. invalid TID) | Check that TID is a valid terminal ID for the equipment and that text length does not exceed equipment limits |
| Values appear as strings instead of numbers | No “type” specified in the list payload | Add “type”: 54 (or the appropriate code) to the JSON payload |
S1F3 Example
Terminal Services (S10F3) Example
Exploring REST emulation and Message Transaction
Using some small scripts, it's possible to create and send messages and manipulate other properties.


