Skip to main content

Bridge a delimiter-framed TCP binary stream into JSON over WebSocket for PlotJuggler.

Project description

pj-bridge

Bridge a delimiter-framed TCP binary stream into JSON over WebSocket for PlotJuggler.

Mode: PlotJuggler runs the WebSocket Server. The bridge connects as a WebSocket client and pushes JSON messages.

What’s in this repo

  • derive_struct.py — Parse a C header (typedef struct { ... } Name;) and derive the Python struct format and expanded field labels.
  • tcp_parser.py — Connect to the device, parse [DE AD BE EF][COUNT][PAYLOAD] × COUNT batches into NDJSON (one JSON per line).
  • socket_client.py — Read NDJSON (stdin or file) and forward to PlotJuggler’s WebSocket Server.
  • bridge.py — One-process solution: connect to device, parse, and forward to PlotJuggler (no shell pipes needed).

Requirements

  • Python 3.12+

  • Device emits batches framed like:

    [ 0xDE 0xAD 0xBE 0xEF ][ COUNT:1 byte ][ PAYLOAD ] * COUNT
    
  • The payload is a packed C struct defined in a header file.

  • PlotJuggler with the WebSocket Server plugin enabled (Protocol: JSON).

Install

python3.12 -m venv .venv
source .venv/bin/activate
pip install -e .

Start PlotJuggler’s WebSocket Server

  • In PlotJuggler: Streaming → WebSocket Server
  • Protocol: JSON
  • Port: for example 9871
  • Click Start

Start Bridge

Connect to device, parse batches, forward to PJ. Default TCP port is 5000; default WS URL is ws://127.0.0.1:9871. Timestamps are in milliseconds by default (--ts-scale 1e-3).

python3 bridge.py \
  --host 192.168.1.91 \
  --struct-header /path/to/telemetry.h \
  --struct-name MyStruct \
  --name-prefix "device_a."

Notes:

  • Add --ws-url ws://<pj_host>:9871 if PlotJuggler runs elsewhere.
  • If needed, guard against corrupted batches with --max-frames-per-batch N.
  • To fall back to single [DELIM][PAYLOAD] (no COUNT), pass --no-counted-batch.

Two-process pipeline (for debugging)

  1. Derive the struct (optional sanity check). Prints JSON describing the derived struct_fmt, fields, and record_size.
python3 derive_struct.py \
  --header /path/to/telemetry.h \
  --struct-name MyStruct \
  1. Parse from device to NDJSON:
python3 tcp_parser.py \
 --host 192.168.1.91 \
 --struct-header /path/to/telemetry.h \
 --struct-name MyStruct \
 --name-prefix "device_a."
  1. Forward NDJSON to PlotJuggler:
python3 tcp_parser.py --host 192.168.1.91 --struct-header /path/to/telemetry.h --struct-name MyStruct | python3 socket_client.py --ws-url ws://127.0.0.1:9871

Field naming

  • All non-timestamp fields are emitted with the optional prefix:

    --name-prefix "device_a."
    

    Example JSON:

    {"t": 1727370023.415, "device_a.ax": 0.02, "device_a.ay": -0.01, "device_a.az": 9.81}
    
  • Arrays like float gyro[3]; become device_a.gyro[0], device_a.gyro[1], device_a.gyro[2].

Timestamp (t)

  • If --ts-field ts_ms is provided, t = ts_ms * --ts-scale (default 1e-3, ms → seconds).
  • If no --ts-field is set, arrival time is used (time.time() in seconds).
  • If your device time is relative (since boot) and you want wall-clock, you can add an epoch offset in code; ask if you want a ready-made flag for that.

Uninstall

  • Deactivate the venv and remove the project directory, or run pip uninstall pj-bridge inside the venv (if installed as a package).

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pj_bridge-0.1.2.tar.gz (12.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pj_bridge-0.1.2-py3-none-any.whl (14.3 kB view details)

Uploaded Python 3

File details

Details for the file pj_bridge-0.1.2.tar.gz.

File metadata

  • Download URL: pj_bridge-0.1.2.tar.gz
  • Upload date:
  • Size: 12.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for pj_bridge-0.1.2.tar.gz
Algorithm Hash digest
SHA256 d6ed8512a606c3dec1a547d6ad9407adc607d797ba9540816d59c9ed54e65e5d
MD5 8121b4b1de8dd754d768fa511011b3f8
BLAKE2b-256 d1b8f1e79d8716625f0dfd1b62ba328a5a493057ecb5c041bbfc258263e94fd2

See more details on using hashes here.

Provenance

The following attestation bundles were made for pj_bridge-0.1.2.tar.gz:

Publisher: pypi-release.yml on DephyInc/pj-bridge

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pj_bridge-0.1.2-py3-none-any.whl.

File metadata

  • Download URL: pj_bridge-0.1.2-py3-none-any.whl
  • Upload date:
  • Size: 14.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for pj_bridge-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 30ee8b0e49f7bea93f6e3cf66fe42cf2e99c45dc6540ddd39dbb7c7be7f46227
MD5 0408056126425b50993fa9485d8aed6e
BLAKE2b-256 5190f1a901cd3bf016783abbbc92dbd45ed38e3c8783b70d3df074b94dcbcf22

See more details on using hashes here.

Provenance

The following attestation bundles were made for pj_bridge-0.1.2-py3-none-any.whl:

Publisher: pypi-release.yml on DephyInc/pj-bridge

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page