====== 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, '''' 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 ''1'' to the corresponding ''sendmessage'' tag - **Monitor** — subscribe to the ''responsestatus'' 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. ==== 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_secsformat00|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 | ''.svrequest.svidlist'' | JSON list (see [[#list_format_secsformat00|List Format]]) | List of SVIDs to request | | Publish | ''.svrequest.responsestatus'' | Plain integer | Seed with ''99'' before triggering | | Publish | ''.svrequest.sendmessage'' | ''1'' | Triggers the S1F3 request | | Subscribe | ''.svrequest.responsestatus'' | Plain integer | Becomes ''0'' on success | | Subscribe | ''.variables.vid.'' | 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 ''99'' to ''e300host.svrequest.responsestatus'' - Publish ''{"values": [30503, 30508], "type": 54}'' to ''e300host.svrequest.svidlist'' - Publish ''1'' to ''e300host.svrequest.sendmessage'' - Wait for ''e300host.svrequest.responsestatus'' to become ''0'' - Read the updated values from ''e300host.variables.vid.clock'' and ''e300host.variables.vid.controlstate'' ==== Status Variable Request (Single) ==== Request a single status variable value. ^ Direction ^ Routing Key ^ Format ^ Description ^ | Publish | ''.svrequestone.svid'' | Plain integer | The SVID to request (e.g. ''30508'' for CLOCK) | | Publish | ''.svrequestone.responsestatus'' | Plain integer | Seed with ''99'' before triggering | | Publish | ''.svrequestone.sendmessage'' | ''1'' | Triggers the request | | Subscribe | ''.svrequestone.responsestatus'' | Plain integer | Becomes ''0'' on success | | Subscribe | ''.variables.vid.'' | Depends on variable | The variable value updates | **Example — request CLOCK only:** - Subscribe to ''e300host.svrequestone.responsestatus'' - Subscribe to ''e300host.variables.vid.clock'' - Publish ''99'' to ''e300host.svrequestone.responsestatus'' - Publish ''30508'' to ''e300host.svrequestone.svid'' - Publish ''1'' to ''e300host.svrequestone.sendmessage'' - Wait for ''e300host.svrequestone.responsestatus'' to become ''0'' - 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 | ''.terminaldisplay.tid'' | Binary byte | Terminal ID (e.g. byte value ''0x01'' for terminal 1) | | Publish | ''.terminaldisplay.text'' | Plain string | The text to display | | Publish | ''.terminaldisplay.responsestatus'' | Plain integer | Seed with ''99'' before triggering | | Publish | ''.terminaldisplay.sendmessage'' | ''1'' | Triggers the S10F3 message | | Subscribe | ''.terminaldisplay.responsestatus'' | Plain integer | Becomes ''0'' on success | **Example — display a message on terminal 1:** - Subscribe to ''e300host.terminaldisplay.responsestatus'' - Publish ''99'' to ''e300host.terminaldisplay.responsestatus'' - Publish byte value ''0x01'' to ''e300host.terminaldisplay.tid'' - Publish ''Hello from the operator'' to ''e300host.terminaldisplay.text'' - Publish ''1'' to ''e300host.terminaldisplay.sendmessage'' - Wait for ''e300host.terminaldisplay.responsestatus'' to become ''0'' ===== Monitoring Output Tags ===== ==== Variable Tags ==== Equipment variables are published to routing keys under ''.variables.vid.'', where '''' 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 '''' | | 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 ===== {{sv_request_updates_variable_tags.png?400|SVID values request }} ===== Terminal Services (S10F3) Example ===== {{terminal_display_send.png?400|Terminal Services }} ===== Exploring REST emulation and Message Transaction ===== Using some small scripts, it's possible to create and send messages and manipulate other properties. [[AMQP:REST Emulation and Message Transaction | Additional Details]]