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.
Most SECS/GEM operations follow a common three-step pattern:
1 to the corresponding sendmessage tagresponsestatus tag 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.
| 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 |
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:
30508
Hello from the operator console
\x01
No JSON wrapper is required for simple types.
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.
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.
{"values": ["recipe1", "recipe2", "recipe3"]}
Without a “type” field and with simple string elements, each item becomes a SecsFormat20 (ASCII) value.
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} ]}
{"values": []}
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} ]}
For report data variables, the format uses a “values” array of “dvid”/“dvval” pairs:
{"values": [ {"dvid": "WaferCount", "dvval": "15"}, {"dvid": "23456", "dvval": "Hello World"} ]}
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):
e300host.svrequest.responsestatuse300host.variables.vid.clocke300host.variables.vid.controlstate99 to e300host.svrequest.responsestatus{“values”: [30503, 30508], “type”: 54} to e300host.svrequest.svidlist1 to e300host.svrequest.sendmessagee300host.svrequest.responsestatus to become 0e300host.variables.vid.clock and e300host.variables.vid.controlstateRequest 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:
e300host.svrequestone.responsestatuse300host.variables.vid.clock99 to e300host.svrequestone.responsestatus30508 to e300host.svrequestone.svid1 to e300host.svrequestone.sendmessagee300host.svrequestone.responsestatus to become 0e300host.variables.vid.clockSend 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:
e300host.terminaldisplay.responsestatus99 to e300host.terminaldisplay.responsestatus0x01 to e300host.terminaldisplay.tidHello from the operator to e300host.terminaldisplay.text1 to e300host.terminaldisplay.sendmessagee300host.terminaldisplay.responsestatus to become 0
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.
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 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 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"}
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.
| 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 |
Using some small scripts, it's possible to create and send messages and manipulate other properties.