abb-rws-mcp 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -5,6 +5,76 @@ All notable changes to abb-rws-mcp are listed in this file. The format follows
5
5
  [Semantic Versioning](https://semver.org/spec/v2.0.0.html). Before 1.0, a new minor
6
6
  version may change tool names, inputs and outputs.
7
7
 
8
+ ## [0.2.0] - 2026-10-31
9
+
10
+ Two new tools, a state line per controller, and a note on where a value came from. The
11
+ tools still read and nothing else: none of them writes to a controller or to the disk.
12
+
13
+ ### Added
14
+
15
+ - **`read_rapid_variable`** reads the value of one RAPID data symbol (a VAR, PERS or
16
+ CONST) through abb-rws-daemon 0.1.1 or later. The value comes as RAPID text, the form
17
+ the controller gives it, with no type (`typed: false`). A value longer than 16384
18
+ characters is cut there and says `truncated: true`. When the controller answers with no
19
+ value at all, the tool says the value was not read (`VALUE_NOT_READ`) and never shows
20
+ it as empty. A task or a module the snapshot does not list is answered without a
21
+ request to the controller. With abb-rws-daemon 0.1.0 the tool says the daemon needs an
22
+ update (`DAEMON_TOO_OLD`), and the other tools work as before.
23
+ - **`explain_event`** lays out one event from the log, by `code` or by `seq` with its
24
+ `feed`. What the controller says (ABB's title, description, causes, consequences and
25
+ actions) is kept apart from our reading of it: the category, the severity and what it
26
+ means, the time and its age, and the RAPID line the event names, read from the module
27
+ when the event gives a module, a routine and a line. The line's task is the one the
28
+ event names, or, when it names none, the one task that lists the module, and the
29
+ answer says which. Next to it are the events just before and after, 60 s each way by
30
+ default (`aroundS`, up to 600). It always says that the data does not show the cause.
31
+ A `seq` without its `feed` gives `FEED_NEEDED`, and a `feed` whose numbering has since
32
+ started over gives `FEED_CHANGED`, because the daemon numbers its events anew after a
33
+ restart.
34
+ - **A state line per controller** in `list_controllers`, such as "motors on, Auto,
35
+ running", and "last known: ..." when the controller's data is not current. A value the
36
+ server does not know reads "not known".
37
+ - **`provenance`** on the answers of `explain_event`, `read_rapid_variable` and
38
+ `read_rapid_source`: the daemon's id for the controller, virtual or real, the RobotWare
39
+ version, when the value was read, whether it came from the daemon's snapshot, the
40
+ controller, this server's cache or a recording the daemon replays, and the RWS resource
41
+ the daemon read, as a template.
42
+ - **`feed` in `summarize_controller`,** so a seq from its problems can be given to
43
+ `explain_event`.
44
+ - **`--mark-codes <file>`** (or `ABB_RWS_MCP_MARK_CODES`): a text file of event codes, one
45
+ per line. Events with a listed code say `marked: true` in `get_event_log`,
46
+ `explain_event` and `summarize_controller`. Without the file every event says
47
+ `marked: null`. The file is read once at start, and a line that is not a code stops the
48
+ server with a message that names the line.
49
+
50
+ ### Changed
51
+
52
+ - `get_robot_position` waits up to 10 s for the first joint sample on an RWS 1.0
53
+ controller (IRC5), where it waited 6 s. On a RobotWare 6.16 virtual controller the
54
+ first sample took 4.2 to 4.5 s and once ran over 6 s while two other controllers were
55
+ read. RWS 2.0 controllers keep 6 s.
56
+ - Tested with snapshot schema 0.15, which abb-rws-daemon 0.1.1 serves, so 0.15 no longer
57
+ logs the warning about a newer schema.
58
+
59
+ ### Tested
60
+
61
+ - On 2026-10-31, through abb-rws-daemon 0.1.1 (snapshot schema 0.15) on three RobotStudio
62
+ virtual controllers: RobotWare 6.16.03 (IRC5, RWS 1.0), 7.21.4 and 8.2.1 (OmniCore,
63
+ RWS 2.0), one controller per run. Every tool and the prompt ran through an MCP client
64
+ over stdio, and every request the server sent the daemon was recorded: GETs only, and
65
+ with motion sampling on, one sampling request per controller.
66
+ - `read_rapid_variable` was compared with the controller's own answer, character for
67
+ character: `tool0` on all three, `reg1` on RobotWare 6, and a PERS string with an inner
68
+ doubled quote and the characters `& < >`, loaded for the run and unloaded after it.
69
+ - `explain_event` was compared with the full event from `get_event_log`. A wrong feed, a
70
+ seq the log does not hold and a seq without its feed each gave their own answer.
71
+
72
+ ### Not yet
73
+
74
+ - Not yet run against a real controller.
75
+ - Not yet run on an event that names a RAPID line, because the test controllers had none
76
+ in their newest 100 events. The line rule is covered by the unit tests.
77
+
8
78
  ## [0.1.0] - 2026-10-25
9
79
 
10
80
  The first release. Its tools only read: none of them writes to a controller or to the disk.
package/README.md CHANGED
@@ -7,31 +7,34 @@ the one session per controller over Robot Web Services: RWS 1.0 (IRC5, RobotWare
7
7
  RWS 2.0 (OmniCore, RobotWare 7 and 8). This server opens no controller session and never
8
8
  sees controller credentials.
9
9
 
10
- > **Status:** 0.1.0. Read-only. Tested on 2026-10-25 through abb-rws-daemon 0.1.0
11
- > (snapshot schema 0.14), and on 2026-10-21 through a pre-release build of it (schema
12
- > 0.13), each time on three RobotStudio virtual controllers: RobotWare 6.16.03 (RWS 1.0),
13
- > 7.21.4 and 8.2.1 (RWS 2.0). Every tool and the prompt ran through an MCP client over
14
- > stdio, and every request the server sent the daemon was recorded: reads only, plus one
15
- > sampling request per controller when motion sampling was on. Not yet run against a real
16
- > controller. Changes are listed in [CHANGELOG.md](CHANGELOG.md).
17
-
18
- **Read-only.** The server has 8 tools and 1 prompt. Every tool reads. None of them sets a
10
+ > **Status:** 0.2.0. Read-only. Tested on 2026-10-31 through abb-rws-daemon 0.1.1
11
+ > (snapshot schema 0.15) on three RobotStudio virtual controllers: RobotWare 6.16.03
12
+ > (RWS 1.0), 7.21.4 and 8.2.1 (RWS 2.0). Every tool and the prompt ran through an MCP
13
+ > client over stdio, and every request the server sent the daemon was recorded: reads
14
+ > only, plus one sampling request per controller when motion sampling was on. On all three,
15
+ > `read_rapid_variable` gave a test string with an inner doubled quote and the characters
16
+ > `& < >` exactly as the controller holds it. 0.1.0 was tested the same way through
17
+ > abb-rws-daemon 0.1.0. Not yet run against a real controller. Changes are listed in
18
+ > [CHANGELOG.md](CHANGELOG.md).
19
+
20
+ **Read-only.** The server has 10 tools and 1 prompt. Every tool reads. None of them sets a
19
21
  signal, starts or stops a program, moves a program pointer, loads or edits a module,
20
22
  switches motors, changes the speed, or requests mastership or write access. There is no
21
23
  write tool behind a flag either. The server writes no file and starts no process. It calls
22
- only the daemon's read routes; the one request that is not a GET asks the daemon to sample
24
+ only the daemon's read routes. The one request that is not a GET asks the daemon to sample
23
25
  joint positions for 15 s (see [Motion sampling](#motion-sampling)).
24
26
 
25
27
  ## Requirements
26
28
 
27
29
  - Node.js 20 or later, on Windows or Linux. macOS follows the Linux paths and is untested.
28
- - [abb-rws-daemon](https://github.com/ichbinmeraj/abb-rws-daemon) 0.1.0 or a later 0.x,
30
+ - [abb-rws-daemon](https://github.com/ichbinmeraj/abb-rws-daemon) 0.1.1 or a later 0.x,
29
31
  running on the same PC, with at least one controller added. This server cannot add one.
30
- It reads snapshot schema 0.13 or a later 0.x. It was tested with 0.14, which
31
- abb-rws-daemon 0.1.0 serves, and with 0.13, which only pre-release builds of the daemon
32
- served. It does not read the field 0.14 adds (whether a lock holder is the FlexPendant).
33
- With a later 0.x it logs one warning that the schema is newer than the ones it was
34
- tested with, and `list_controllers` says the same.
32
+ With abb-rws-daemon 0.1.0 every tool works but `read_rapid_variable`, which says the
33
+ daemon needs an update. The server reads snapshot schema 0.13 or a later 0.x. It was
34
+ tested with 0.15, which abb-rws-daemon 0.1.1 serves, and with 0.14 and 0.13 before. It
35
+ does not read the field 0.14 adds (whether a lock holder is the FlexPendant). With a
36
+ later 0.x it logs one warning that the schema is newer than the ones it was tested
37
+ with, and `list_controllers` says the same.
35
38
  - An MCP host that runs stdio servers: Claude Desktop, Claude Code, VS Code, Cursor or
36
39
  another.
37
40
 
@@ -45,7 +48,7 @@ Claude Desktop (`claude_desktop_config.json`) and Cursor (`~/.cursor/mcp.json`):
45
48
  ```json
46
49
  {
47
50
  "mcpServers": {
48
- "abb-rws": { "command": "npx", "args": ["-y", "abb-rws-mcp@0.1.0"] }
51
+ "abb-rws": { "command": "npx", "args": ["-y", "abb-rws-mcp@0.2.0"] }
49
52
  }
50
53
  }
51
54
  ```
@@ -55,7 +58,7 @@ VS Code (`.vscode/mcp.json`):
55
58
  ```json
56
59
  {
57
60
  "servers": {
58
- "abb-rws": { "type": "stdio", "command": "npx", "args": ["-y", "abb-rws-mcp@0.1.0"] }
61
+ "abb-rws": { "type": "stdio", "command": "npx", "args": ["-y", "abb-rws-mcp@0.2.0"] }
59
62
  }
60
63
  }
61
64
  ```
@@ -63,7 +66,7 @@ VS Code (`.vscode/mcp.json`):
63
66
  Claude Code:
64
67
 
65
68
  ```sh
66
- claude mcp add abb-rws -- npx -y abb-rws-mcp@0.1.0
69
+ claude mcp add abb-rws -- npx -y abb-rws-mcp@0.2.0
67
70
  ```
68
71
 
69
72
  The daemon on another port: add `"env": { "ABB_RWS_MCP_DAEMON_URL": "http://127.0.0.1:7811" }`
@@ -77,16 +80,39 @@ nothing else.
77
80
 
78
81
  ## Tools
79
82
 
80
- | Tool | What it answers | Reaches the controller? |
81
- |---|---|---|
82
- | `summarize_controller` | Start here. The state in one sentence, facts from the snapshot, recent errors and warnings with ABB's recommended actions, the operational messages, and the source line at each program pointer | At most two module reads, failed ones included |
83
- | `list_controllers` | The controllers the daemon knows, and the daemon's own state. Call it first, and when other tools fail | No |
84
- | `get_controller_status` | Controller state, operating mode, speed override, collision detection, RAPID execution, the link, what the daemon can read here, and the access status as the controller reported it | No |
85
- | `get_robot_position` | Joint positions, the TCP pose with Euler angles, whether the arm moves, how close each joint is to its limits | Motion sampling, see below |
86
- | `read_io_signals` | Signals and values from the daemon's signal table, or a signal search | Only for a search |
87
- | `get_event_log` | The controller's event log as the daemon keeps it, filtered by severity, time, category or code | No |
88
- | `get_rapid_execution` | Execution state and the program and motion pointers of each task | No |
89
- | `read_rapid_source` | A module's RAPID source with line numbers: a routine, the lines around a line, or a page | The first read of a module |
83
+ Each tool below says what it answers, then whether it reaches the controller.
84
+
85
+ - `summarize_controller`: start here. The state in one sentence, facts from the snapshot,
86
+ recent errors and warnings with ABB's recommended actions, the operational messages, and
87
+ the source line at each program pointer. It reaches the controller for at most two module
88
+ reads, failed ones included.
89
+ - `list_controllers`: the controllers the daemon knows, each with a state line ("motors on,
90
+ Auto, running"), and the daemon's own state. Call it first, and when other tools fail. It
91
+ does not reach the controller.
92
+ - `get_controller_status`: controller state, operating mode, speed override, collision
93
+ detection, RAPID execution, the link, what the daemon can read here, and the access status
94
+ as the controller reported it. It does not reach the controller.
95
+ - `get_robot_position`: joint positions, the TCP pose with Euler angles, whether the arm
96
+ moves, how close each joint is to its limits. It reaches the controller through motion
97
+ sampling, see below.
98
+ - `read_io_signals`: signals and values from the daemon's signal table, or a signal search.
99
+ It reaches the controller only for a search.
100
+ - `get_event_log`: the controller's event log as the daemon keeps it, filtered by severity,
101
+ time, category or code. It does not reach the controller.
102
+ - `explain_event`: one event laid out for explaining it. What the controller says (ABB's
103
+ description, causes, consequences and actions) is kept apart from our reading (category,
104
+ severity, time, the RAPID line the event names), next to the events just before and after.
105
+ It does not say what caused the event. Name the event by its code, or by its seq together
106
+ with the feed from the same answer. It reaches the controller once, to read the module of
107
+ the line the event names.
108
+ - `get_rapid_execution`: execution state and the program and motion pointers of each task.
109
+ It does not reach the controller.
110
+ - `read_rapid_source`: a module's RAPID source with line numbers, as a routine, the lines
111
+ around a line, or a page. It reaches the controller on the first read of a module.
112
+ - `read_rapid_variable`: the value of one RAPID data symbol as RAPID text, the form the
113
+ controller gives it, with no type. A value the controller answers with no value at all is
114
+ said so, never shown as empty. Needs abb-rws-daemon 0.1.1. It reaches the controller
115
+ unless the daemon read the same value in the last 2 s.
90
116
 
91
117
  The prompt `why_did_it_stop` (a slash command in hosts that show prompts) asks the
92
118
  assistant to find out what a controller is doing and why it stopped, with a fixed recipe:
@@ -104,8 +130,14 @@ signals that line names, the age of every value, and only causes the data shows.
104
130
  unknown" when the daemon could not read the controller's clock.
105
131
  - Controller states and modes come with a one-sentence meaning where ABB's documentation
106
132
  describes the value.
107
- - A daemon that replays a recording is refused unless replay is allowed; then every answer
133
+ - A daemon that replays a recording is refused unless replay is allowed. Then every answer
108
134
  says REPLAY.
135
+ - `explain_event`, `read_rapid_variable` and `read_rapid_source` also say where the value
136
+ came from, in `provenance`: the daemon's id for the controller (the same id every answer
137
+ starts with, which the daemon may make from the system name), virtual or real, the
138
+ RobotWare version, when the value was read, whether it came from the daemon's snapshot,
139
+ the controller, this server's cache or a recording the daemon replays, and the RWS
140
+ resource the daemon read, as a template.
109
141
  - Each answer has a readable text part and the same data as structured JSON.
110
142
 
111
143
  ## Controller text is data
@@ -116,8 +148,12 @@ text. abb-rws-mcp passes it to the assistant marked as controller data, not as i
116
148
  in the text, inside a block whose markers carry a random value made for that answer, and in
117
149
  the structured JSON, under `controllerData`. Escape sequences are removed from it, and hidden
118
150
  characters (control, zero-width, direction and tag characters) are replaced by a visible mark
119
- (U+FFFD). This server has no tool that changes anything, so that text cannot make it act. Other
120
- tools your assistant has can still act. Read what the assistant proposes before you run it.
151
+ (U+FFFD). A few short values also appear outside that block, in the status line, the RAPID
152
+ line an event names and `provenance`: the controller id, the RobotWare version, and task,
153
+ module and routine names. They appear there only when they have the form of an id, a version
154
+ number or a RAPID name, and are left out otherwise. This server has no tool that changes
155
+ anything, so controller text cannot make it act. Other tools your assistant has can still
156
+ act. Read what the assistant proposes before you run it.
121
157
 
122
158
  ## Motion sampling
123
159
 
@@ -126,7 +162,7 @@ unless another program already does. These are controller reads, the ones the da
126
162
  README lists under "Reads on demand": about 8 joint reads a second per mechanical unit and
127
163
  2 pose reads a second per robot, while the sampling runs. The server asks at most once per
128
164
  15 s per controller, and never while the link is not live or the controller reports that
129
- it is busy. Turn it off with `--motion-sampling off`; the tool then returns the last sampled
165
+ it is busy. Turn it off with `--motion-sampling off`. The tool then returns the last sampled
130
166
  values with their time.
131
167
 
132
168
  ## Signals
@@ -135,8 +171,8 @@ The signal table is read from the daemon's memory, with values of unknown age. A
135
171
  device, network or category, or a read with `fresh: true`, is a read-only RWS search request
136
172
  on the controller (sent as a POST by the daemon, not a GET). A search needs a name prefix of
137
173
  at least 3 characters or a device, so it does not page through the whole table. This server
138
- limits its own controller reads (searches and module reads): per controller, one at a time,
139
- at most two in a row, then one every 2 s.
174
+ limits its own controller reads (searches, module reads and value reads): per controller,
175
+ one at a time, at most two in a row, then one every 2 s.
140
176
 
141
177
  ## What it cannot see
142
178
 
@@ -146,21 +182,35 @@ at most two in a row, then one every 2 s.
146
182
  operational events in the log are the only timing evidence.
147
183
  - The daemon keeps the last 256 event-log messages per controller. Older ones are not
148
184
  available.
149
- - RAPID variables, backups, configuration and controller files are not served by the
150
- daemon yet, so this server cannot read them.
185
+ - Backups, configuration and controller files are not served by the daemon yet, so this
186
+ server cannot read them.
187
+ - A RAPID value comes as text. The controller gives no type with it, so this server shows
188
+ none.
151
189
 
152
190
  ## Configuration
153
191
 
154
- Each option has an environment variable. An option wins over its variable; an empty
192
+ Each option has an environment variable. An option wins over its variable. An empty
155
193
  variable counts as unset.
156
194
 
157
- | Option | Variable | Default and meaning |
158
- |---|---|---|
159
- | `--daemon-url <url>` | `ABB_RWS_MCP_DAEMON_URL` | `http://127.0.0.1:7810`. Only `http://127.0.0.1:<port>` or `http://localhost:<port>`. `localhost` is a spelling only: the server always connects to 127.0.0.1. Every other host, `[::1]` included, is refused at start. |
160
- | `--token-file <file>` | `ABB_RWS_DAEMON_TOKEN_FILE` | The daemon's own default: `%APPDATA%\abb-rws-daemon\token` on Windows, `$XDG_CONFIG_HOME/abb-rws-daemon/token` or `~/.config/abb-rws-daemon/token` elsewhere. The variable is the one the daemon reads, so setting it once serves both. |
161
- | `--allow-replay` | `ABB_RWS_MCP_ALLOW_REPLAY` | Off. Read a daemon that replays a recording; every answer then says REPLAY. |
162
- | `--motion-sampling <on\|off>` | `ABB_RWS_MCP_MOTION_SAMPLING` | `on`. See [Motion sampling](#motion-sampling). |
163
- | | `ABB_RWS_MCP_LOG` | `warn`. `error`, `warn`, `info` or `debug`. Logs go to stderr only. |
195
+ - `--daemon-url <url>`, variable `ABB_RWS_MCP_DAEMON_URL`. Default
196
+ `http://127.0.0.1:7810`. Only `http://127.0.0.1:<port>` or `http://localhost:<port>`.
197
+ `localhost` is a spelling only: the server always connects to 127.0.0.1. Every other host,
198
+ `[::1]` included, is refused at start.
199
+ - `--token-file <file>`, variable `ABB_RWS_DAEMON_TOKEN_FILE`. Default is the daemon's own:
200
+ `%APPDATA%\abb-rws-daemon\token` on Windows, `$XDG_CONFIG_HOME/abb-rws-daemon/token` or
201
+ `~/.config/abb-rws-daemon/token` elsewhere. The variable is the one the daemon reads, so
202
+ setting it once serves both.
203
+ - `--allow-replay`, variable `ABB_RWS_MCP_ALLOW_REPLAY`. Off by default. Read a daemon that
204
+ replays a recording. Every answer then says REPLAY.
205
+ - `--motion-sampling <on|off>`, variable `ABB_RWS_MCP_MOTION_SAMPLING`. Default `on`. See
206
+ [Motion sampling](#motion-sampling).
207
+ - `--mark-codes <file>`, variable `ABB_RWS_MCP_MARK_CODES`. Off by default. A text file of
208
+ event codes, one per line (`#` starts a comment). Events with a listed code say
209
+ `marked: true` in `get_event_log`, `explain_event` and `summarize_controller`, so you can
210
+ find them before you share an answer. Without a file every event says `marked: null`. The
211
+ file is read once at start.
212
+ - `ABB_RWS_MCP_LOG`, a variable with no option. Default `warn`. `error`, `warn`, `info` or
213
+ `debug`. Logs go to stderr only.
164
214
 
165
215
  `--help` and `--version` print and exit without contacting anything. A bad value stops the
166
216
  server at start with one line on stderr.
@@ -175,7 +225,7 @@ server reads the daemon on the same PC.
175
225
  never in a tool result.
176
226
  - The daemon's token file opens the whole daemon API (adding controllers, discovery scans,
177
227
  shutdown) to every program that runs under your account, an assistant's shell tool
178
- included. This server uses only the read routes; other tools are not bound by that.
228
+ included. This server uses only the read routes. Other tools are not bound by that.
179
229
  - Tool results go to your assistant's model provider. They can include controller and
180
230
  system names, the daemon's controller names (which default to the address), and the user
181
231
  or PC names of lock holders.
@@ -214,7 +264,7 @@ The tests never reach a controller or a daemon.
214
264
 
215
265
  ## Related projects
216
266
 
217
- - [abb-rws-daemon](https://github.com/ichbinmeraj/abb-rws-daemon): one session per controller, served as a typed snapshot over HTTP and WebSocket; this server's only way to a controller
267
+ - [abb-rws-daemon](https://github.com/ichbinmeraj/abb-rws-daemon): one session per controller, served as a typed snapshot over HTTP and WebSocket, and this server's only way to a controller
218
268
  - [abb-rws-client](https://github.com/ichbinmeraj/abb-rws-client): TypeScript RWS client tested on RobotWare 6, 7 and 8
219
269
  - [abb-rws-ros2](https://github.com/ichbinmeraj/abb-rws-ros2): ROS 2 supervisory bridge
220
270
  - [abb-rws-vscode](https://github.com/ichbinmeraj/abb-rws-vscode): RAPID Live, VS Code extension for ABB controllers
@@ -229,6 +279,8 @@ Contributions are accepted under the DCO - see [CONTRIBUTING.md](CONTRIBUTING.md
229
279
 
230
280
  ## Disclaimer
231
281
 
232
- Independent open-source project by [Meraj Safari](https://github.com/ichbinmeraj). Not
233
- affiliated with, endorsed by or sponsored by ABB. ABB, RobotWare, OmniCore, IRC5, RAPID,
234
- FlexPendant and RobotStudio are trademarks of ABB. See [TRADEMARKS.md](TRADEMARKS.md).
282
+ Independent open-source project by [Meraj Safari](https://github.com/ichbinmeraj). ABB is
283
+ a trademark of ABB Asea Brown Boveri Ltd. RobotWare, OmniCore, IRC5, RAPID, FlexPendant
284
+ and RobotStudio are trademarks of their respective owners. Not affiliated with, endorsed
285
+ by, sponsored by or supported by ABB, ABB Robotics or any later owner of these products.
286
+ See [TRADEMARKS.md](TRADEMARKS.md).
package/TRADEMARKS.md CHANGED
@@ -1,16 +1,17 @@
1
1
  # Trademarks and project names
2
2
 
3
- ## ABB's marks
3
+ ## The marks named here
4
4
 
5
- ABB, IRC5, OmniCore, RobotWare, RobotStudio, RAPID, FlexPendant, GoFa and
6
- Robot Web Services are trademarks or registered trademarks of ABB Ltd.
5
+ ABB is a trademark of ABB Asea Brown Boveri Ltd. IRC5, OmniCore, RobotWare,
6
+ RobotStudio, RAPID, FlexPendant, GoFa and Robot Web Services are trademarks or
7
+ registered trademarks of their respective owners.
7
8
 
8
- **This project is not affiliated with, endorsed by, sponsored by, or supported
9
- by ABB Ltd.** It is an independent, clean-room implementation built from
10
- publicly available documentation and from observed behaviour of controllers the
11
- maintainer operates.
9
+ **This project is not affiliated with, endorsed by, sponsored by or supported by
10
+ ABB, ABB Robotics or any later owner of these products.** It is an independent,
11
+ clean-room implementation built from publicly available documentation and from
12
+ the observed behaviour of RobotStudio virtual controllers.
12
13
 
13
- ## Why ABB's marks appear here
14
+ ## Why these marks appear here
14
15
 
15
16
  They appear for one reason only: to describe accurately what this software is
16
17
  compatible with. Software that speaks ABB Robot Web Services cannot be described
@@ -37,20 +38,23 @@ which is why the rest of this section exists.
37
38
 
38
39
  **What this project will not do:**
39
40
 
40
- - Use ABB's logo, wordmark, colours, product photography, or any part of ABB's
41
- visual identity.
42
- - Describe itself as official, certified, approved, endorsed, or supported by
43
- ABB, or use phrasing that invites that reading.
41
+ - Use the logo, wordmark, colours, product photography or any part of the visual
42
+ identity of ABB, ABB Robotics or a later owner of these products.
43
+ - Describe itself as official, certified, approved, endorsed or supported by
44
+ ABB, ABB Robotics or a later owner of these products, or use phrasing that
45
+ invites that reading.
44
46
  - Apply to register `abb-rws-*` or any confusingly similar mark, anywhere.
45
- - Sell, license, or offer paid support for this software under ABB's name.
46
- - Use ABB's marks as anything other than a plain-text reference to ABB's own
47
- products.
48
-
49
- **If ABB asks us to change the naming, we will.** No argument, no delay for
50
- negotiation. In practice that means: new package names published within 30 days
51
- of a written request, the old names marked deprecated with a pointer to the new
52
- ones so existing users are not stranded, and repositories renamed with redirects
53
- left in place. Reach the maintainer through the contact route below.
47
+ - Sell, license, or offer paid support for this software under the name of any
48
+ of these owners.
49
+ - Use these marks as anything other than a plain-text reference to the products
50
+ they name.
51
+
52
+ **If ABB, ABB Robotics or a later owner of these products asks us to change the
53
+ naming, we will.** No argument, no delay for negotiation. In practice that
54
+ means: new package names published within 30 days of a written request, the old
55
+ names marked deprecated with a pointer to the new ones so existing users are not
56
+ stranded, and repositories renamed with redirects left in place. Reach the
57
+ maintainer through the contact route below.
54
58
 
55
59
  We would rather be told early and fix it cheaply than discover a problem once
56
60
  other projects depend on these names.