From dc3a0f8b0b4627bd41dea172da29f9532143a03c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?I=C3=B1igo=20Etxaniz?= Date: Tue, 4 Aug 2026 09:45:44 +0200 Subject: [PATCH] Correct the signals framing in the README signals.yml is managed by the sidecar, not authored by the customer, and the write flag is used by the supporting services rather than being a script author's lever. The previous text presented both as a customer contract, which is wrong. Now claims only runtime behaviour: which signals a job sees is configured for it, an unexposed signal is absent rather than an error, and batch rejection is described as the sidecar not recognising an id. Also points a customer at their own job output rather than platform-side logs they may not have access to. --- README.md | 29 ++++++++++++----------------- 1 file changed, 12 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index 136e79b..cc6a47e 100644 --- a/README.md +++ b/README.md @@ -43,18 +43,12 @@ other submodule paths work equally well. ## Signals -A signal is reachable from a script only if it is listed in the job's `signals.yml`, with -`read: 1` to appear in `plant.state` and `write: 1` to accept a write. Ids and names both -come from that file and must match the ids configured in i7state. +Not every signal is available to every job. `plant.state` holds only the signals the job's +sidecar exposes to it, keyed by both id and name. Which those are is configured for the job; +a script does not declare them. -```yaml -- { id: 21, name: 'oven-temperature', read: 1, write: 0 } -- { id: 49, name: 'oven-output', read: 0, write: 1 } -``` - -A signal missing from `signals.yml`, or listed with `read: 0`, is simply absent from -`plant.state` — it does not raise. Guard with `in` or `.get()` rather than assuming a key -exists. +A signal that is not exposed is simply absent from `plant.state` — reading it does not raise. +Guard with `in` or `.get()` rather than assuming a key is there. ## i7lib.client @@ -85,9 +79,9 @@ call `run` uses; it is what keeps a script in step with the sample clock instead **`add(signal_id, value, name="")`** — queues one write. `signal_id` is coerced to `int`, `value` to `float`, `name` to `str`. -A batch is **all or nothing**. If any id in it is not in the job's `signals.yml`, the sidecar -rejects the entire batch and none of the writes land. Ids that are known but not marked -`write: 1` are skipped without failing the batch. Neither outcome is visible to the caller — +A batch is **all or nothing**. If the sidecar does not recognise one of the ids in it, the +entire batch is rejected and none of the writes land. An id it does recognise but which is +not writable is skipped without failing the batch. Neither outcome is visible to the caller — see Error handling below. ### `run(logic_func, interval_ms=1000, offset_ms=200)` @@ -141,6 +135,7 @@ rows" alike; `send` returning normally does **not** mean the writes were applied rejected in full for one unknown id looks exactly like a successful send from inside the script. -So when a value is not moving, check the job's stdout for the printed error first, then the -sidecar and i7state logs, which record every write as applied, rejected or unknown. Do not -infer success from the absence of an exception. +So when a value is not moving, check the job's own output first — that is where this library +prints its errors. If nothing appears there, the write reached the platform and was rejected +or dropped further in, which is visible only in the platform-side logs. Do not infer success +from the absence of an exception.