Skip to content

DYODE 1.0.0

Choose a tag to compare

@github-actions github-actions released this 08 Oct 02:19
d582906

First release of the Python 3 port of
wavestone-cdt/dyode.

Supported systems

System CPU Python
Ubuntu 24.04 LTS amd64, arm64 3.12
Ubuntu 26.04 LTS amd64, arm64 3.14
Raspberry Pi OS 12 "bookworm", 64-bit arm64 3.11
Raspberry Pi OS 13 "trixie", 64-bit arm64 3.13

Ubuntu 22.04 is not supported: its python3 is 3.10, older than DYODE
requires. 32-bit Raspberry Pi OS is not covered by the offline bundle.

Installation

  • install.sh installs a box from scratch: OS packages (udpcast, Python
    venv support), a virtualenv built on the machine itself, and DYODE's Python
    packages, then starts the setup wizard. Choose --online (apt and PyPI) or
    --offline, or let it ask.
  • Offline installs need no network at all. The repository ships every
    Python package as wheels (Python 3.11–3.14, x86_64 and aarch64) and the OS
    packages for each supported system. The bundle is checked against
    SHA256SUMS before anything changes; OS packages go through a private
    local apt repository, so apt installs only what is missing and never
    downgrades.
  • The bundle is rebuilt on GitHub by the Offline install bundle workflow,
    or by hand with tools/build_wheelhouse.sh and tools/build_debs.sh.
  • A venv/ copied in from another folder or revision is detected and
    rebuilt rather than trusted.

Setup

  • Guided setup wizard (dyode_setup.py), curses or plain text: picks the
    diode interface, reads its MAC address, configures modules, and writes
    config.yaml and a systemd unit.
  • The generated systemd unit waits for the diode interface and its address,
    restarts with it after a link flap, and never gives up retrying.

File transfer

  • Received files are identified by content, not arrival order. Previously a
    single lost transfer shifted every later file by one and discarded the
    rest of the batch.
  • The receiver no longer stops listening while it verifies a file, and the
    sender pauses between files (file_gap), since a diode offers no
    handshake.
  • Sent files are kept in .dyode_sent/ for keep_sent_hours instead of
    being deleted: a diode cannot confirm delivery.
  • Incoming files are staged outside the output folder, so NFS, SFTP or
    anything else serving it never sees a partial file.
  • The static ARP entry is set before starting and re-asserted continuously;
    without it nothing reaches the output side while both ends report success.
  • Forward error correction is configurable per module (fec, or none for
    full line rate on a clean link).
  • An idle udp-receiver timeout is recognised from timing and bytes
    received rather than its wording, so it is no longer logged as an error.

Logging

  • /var/log/dyode-transfer/dyode.log (human-readable) and transfer.jsonl
    (one JSON event per line for monitoring tools), with file_missing events
    naming every file that never arrived.
  • Rotation by logrotate, weekly archives by a systemd timer.

Python 3 port

  • Runs on Python 3.11+, pymodbus 3.11–3.12 on asyncio, inotify_simple.
  • JSON replaces pickle on every network path, removing remote code
    execution on the output box; framing is length-prefixed and CRC-checked.
  • File names are passed to udpcast as argument lists, never through a shell.
  • Datastores are sized from the configured register ranges, so addresses
    such as 400–449 are served where SCADA expects them.

Verified

Beyond the unit tests, this release was installed offline with the real
bundle on Ubuntu 24.04, transferred a file through real udpcast using
DYODE's own command lines, and round-tripped Modbus values through real
pymodbus 3.12.1.