Skip to content

The review of Evok 3.1: a failed pulse, an empty API section, MQTT errors - #277

Merged
miroslav-ondra merged 2 commits into
dev-3.1from
dev-3.1-review-fixes
Oct 26, 2026
Merged

miroslav-ondra merged 2 commits into
dev-3.1from
dev-3.1-review-fixes

Conversation

@miroslav-ondra

@miroslav-ondra miroslav-ondra commented Oct 26, 2026 •

Copy link
Copy Markdown
Contributor

The findings of the review of #276 (Evok 3.1.0), fixed in dev-3.1 before the release.

Changes

A failed pulse left the output on (blocks/device.py, modbus/base.py)

  • start_pulse() cancelled the running sequence before it wrote the new value. When the write failed (an unavailable unit, an error of the communication), the old pulse was gone without its end and the output stayed on.
  • set_devices(..., sequences={output: pulse}): the new sequence is started after the successful set(), under the lock of the unit, it replaces the running one, whose step waiting for the lock writes nothing. A failed write leaves the old sequence running and it writes its end (with check_available=False). The pulse runs also when the task is cancelled during the read after the write, e.g. at the shutdown.
  • The behavior changed in one case: when the end of the old pulse already waits for the lock before the new pulse, it is written first (the output goes off) and then the new pulse; before, the new pulse cancelled it.

An empty section of an API stopped the start (config.py)

  • websocket: or webhook: with all options commented out is None in YAML, evok.py failed on .get(). The sections rpc, websocket, webhook and mqtt are normalized when the config is read: an empty one is {}, another value than a mapping (e.g. websocket: true) is an error of the config and Evok exits with it.

MQTT stopped silently (mqtt_handler.py)

  • An error of the connection which is not an MqttError, e.g. a missing CA file of TLS, ended the loop of the connection without a log. It is logged once with its traceback (also when it comes after each connection) and the handler connects again after RECONNECT_DELAY.
  • An MqttError of a publish (e.g. a full queue of the client) ended the publishing task while the connection stayed open, no state was published any more. The state is published again after the other pending ones, at most 3 times 1 s apart, then dropped (e.g. refused by the size or the ACL of the broker); a lost connection ends the loop of the commands, which cancels the publishing as before.

REST (evok.py)

  • An empty body with Content-Type: application/json sets nothing as without the header, it was a 400.

Docs and CI

  • api-changes-dev-src.md compiled against Evok 3.0.6; main after it had only the docs and Fix websocket blocking requests #191.
  • EVOK_VER=3.1.0 and the links to the udev rule and examples/config.yaml on the tag 3.1.0, the tag of the release (they are 404 until it exists).
  • sequencer.md: a new pulse replaces the running one after its write.
  • The integration tests run on the pushes to dev-*, not dev-3.1.

Testing

  • pytest tests: 1254 passed; new tests: the failed pulse (the old one writes its end), the pulse cancelled after its write, the end of the old pulse before the new one, the new pulse before the end of the old one, the empty section of an API, a section which is not a mapping, the other error of the MQTT connection and after the connection, the failed and the dropped publish, the empty JSON body. Each fails without its fix. ruff check and ruff format --check src clean.
  • Patron M527 (192.168.221.159): a pulse of 1 s of led ext2_01 replaced by a pulse of 2 s, the LED stays on after 1.3 s, off after 2.3 s; an empty JSON body to /rest/led/ext2_01 is 200.

🤖 Generated with Claude Code

miroslav-ondra and others added 2 commits October 26, 2026 20:13
…rors

- start_pulse() cancels the running sequence of the output after the
  successful write of the new value, under the lock of the unit
  (set_devices(replace_sequences=True)): a failed write, e.g. an unavailable
  unit, left the output in the state of the old pulse without its end
- get_api() of an empty section (websocket: with the options commented out)
  is {}, Evok did not start
- MQTT: an error of the connection which is not an MqttError (e.g. a missing
  file of TLS) is logged once and the handler connects again, the loop ended
  silently; an MqttError of a publish publishes the state again after the
  delay, the publishing task ended silently and the states were not published
- /rest: an empty body with Content-Type application/json sets nothing, it was
  a 400
- docs: the API changes against Evok 3.0.6 (main after it had the docs and
  #191); EVOK_VER=3.1.0 and the links to the tag 3.1.0; the replacement of
  a pulse in sequencer.md
- CI: the integration tests on the pushes to dev-*, not dev-3.1
- tests: the failed pulse, the old end before the new pulse, the empty section,
  the MQTT errors, the empty JSON body

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…rrors, the API sections

- set_devices(sequences={device: Sequence}) starts the new sequence after the
  successful set() under the lock of the unit, it replaces the running one;
  start_pulse() started the pulse after the read of the unit, a task cancelled
  meanwhile left the output on without a sequence
- MQTT: a state refused by the client is published again after the other
  pending ones, at most 3 times with 1 s between them, then dropped; it was
  retried every 5 s forever and delayed the others. An error other than of
  MQTT is logged once also when it comes after each connection, the message
  says so
- the sections rpc, websocket, webhook and mqtt of apis are normalized when the
  config is read: an empty one is {}, another value than a mapping is an error
  of the config, Evok exits with it (also apis which is not a mapping); the
  callers do not repeat `or {}`
- tests: the pulse cancelled after its write, the dropped publish, the error
  after the connection, the API sections which are not a mapping

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@miroslav-ondra
miroslav-ondra merged commit 7649a19 into dev-3.1 Oct 26, 2026
6 checks passed
@miroslav-ondra
miroslav-ondra deleted the dev-3.1-review-fixes branch October 26, 2026 19:27
miroslav-ondra added a commit that referenced this pull request Oct 26, 2026
The links of the docs and EVOK_VER on the tag 3.1.0 and the API changes against
Evok 3.0.6 of dev-3.1 replace the links to main and the wording of the release
commits.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@miroslav-ondra miroslav-ondra mentioned this pull request Oct 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant