Skip to main content

A relay for forwarding Foxglove WebSocket messages to a ZMQ server.

Project description

Foxglove to ZMQ Relay

A Python utility to connect to a Foxglove WebSocket server, decode messages (JSON and Protobuf), and relay them to and from a ZMQ server using either a PUSH/PULL or PUB/SUB pattern.

An image of a terminal showing foxglove2zmq in use in PUSH-PULL mode

This is useful for integrating Foxglove data streams with other backend services, logging systems, or robotics frameworks that use ZMQ for messaging. The relay is also bi-directional: Client publishing is fully supported from ZMQ to Foxglove. Also includes a command-line interface (foxglove2zmq) for easy setup and configuration!

Features

  • Connects to any Foxglove WebSocket Server: Natively connects using the foxglove.sdk.v1 subprotocol.
  • Automatic Channel Discovery: Discovers all available channels on connect.
  • Topic Filtering: Easily blocklist topics you don't want to relay.
  • Multi-Encoding Support: Decodes both standard json and protobuf encoded messages on the fly.
  • Dynamic Protobuf Decoding: Parses Protobuf schemas (FileDescriptorSet) provided by the server to decode binary payloads into JSON.
  • Bi-Directional Communication:
    • Supports sending messages from ZMQ to Foxglove using ClientPublish messages without any setup.
    • Can handle parameter updates and other client-side interactions.
  • Command-Line Interface: Provides a simple CLI for running the relay with various options.
  • Flexible ZMQ Patterns:
    • PUSH/PULL: Relays all messages to a single stream for worker distribution.
    • PUB/SUB: Publishes messages on their original Foxglove topic for selective subscription.
  • Handles Large Messages: Configured to accept WebSocket messages of any size.

Todo

  • Add support for bi-directional messaging with:
  • Add support for other binary messages:
    • 0x01 - Client channel responses
    • 0x02 - Time
    • 0x03 - Service call responses
    • 0x04 - Fetch asset responses
  • Add support for Flatpack encoded messages and ROS1/ROS2 message types.

Installation

You can install the package from PyPI:

pip install foxglove-zmq-relay

Alternatively, you can install it directly from the GitHub repository:

pip install git+https://github.com/helkebir/foxglove2zmq.git

Dependencies

This package requires Python 3.9 or higher and the following dependencies:

  • websockets>=10.0: For WebSocket communication with the Foxglove server.
  • pyzmq>=22.0: For ZeroMQ communication.
  • protobuf>=3.19: For Protobuf message decoding.

Usage

The relay is designed to be run as a standalone script. You can import and use the classes in your own applications.

Command-Line Examples

A basic script is provided to run the relay from the command line. You can choose which ZMQ pattern to use. Currently, the PUSH/PULL and PUB/SUB patterns are implemented.

A command-line interface is available via the foxglove2zmq command after installation.

foxglove2zmq --help
usage: foxglove2zmq [-h] -p {push,pub} [-w FOXGLOVE_WS] -z ZMQ_BIND [-v VERBOSITY] [-b [BLOCKLIST ...]] [--timeout TIMEOUT]

Relay Foxglove WebSocket messages to a ZMQ server.

optional arguments:
  -h, --help            show this help message and exit
  -p {push,pub}, --pattern {push,pub}
                        The ZMQ socket pattern to use ('push' for PUSH/PULL or 'pub' for PUB/SUB).
  -w FOXGLOVE_WS, --foxglove-ws FOXGLOVE_WS
                        The WebSocket URL of the Foxglove server (e.g., ws://localhost:8765).
  -z ZMQ_BIND, --zmq-bind ZMQ_BIND
                        The TCP address for the ZMQ server to bind to (e.g., tcp://localhost:5555).
  -v VERBOSITY, --verbosity VERBOSITY
                        The verbosity level (0 = errors only, 1 = info, 2 = debug).
  -b [BLOCKLIST ...], --blocklist [BLOCKLIST ...]
                        A space-separated list of topics to ignore (e.g., /diagnostics /debug).
  --timeout TIMEOUT     Time in seconds to wait for channel advertisements.

PUSH/PULL Relay

This is the simplest pattern. It sends all messages from all topics to any connected ZMQ PULL client.

# In one terminal, run the relay
foxglove2zmq --pattern push --foxglove-ws ws://localhost:8765 --zmq-bind tcp://localhost:5555

And in another terminal, run a ZMQ PULL client to receive messages:

# ZMQ PULL client example (client.py)
import zmq
import json

context = zmq.Context()
socket = context.socket(zmq.PULL)
socket.connect("tcp://localhost:5555")

print("Receiving messages...")
while True:
    msg_str = socket.recv_string()
    msg_obj = json.loads(msg_str)
    print(json.dumps(msg_obj, indent=2))

PUB/SUB Relay

This pattern publishes each message on its original Foxglove topic. ZMQ SUB clients can then subscribe to specific topics.

# In one terminal, run the relay
foxglove2zmq --pattern pub --foxglove-ws ws://localhost:8765 --zmq-bind tcp://localhost:5555

And in another terminal, run a ZMQ SUB client to receive messages from a specific topic:

# ZMQ SUB client example (client.py)
import zmq
import json

context = zmq.Context()
socket = context.socket(zmq.SUB)
socket.connect("tcp://localhost:5555")

# Subscribe to a specific topic (e.g., /sensor/camera)
# To subscribe to all topics, use b""
socket.setsockopt(zmq.SUBSCRIBE, b"/sensor/camera")

print("Receiving messages...")
while True:
    topic, msg_str = socket.recv_multipart()
    msg_obj = json.loads(msg_str)
    print(f"Topic: {topic.decode()}")
    print(json.dumps(msg_obj, indent=2))

Library Usage

You can also import the classes into your own Python application for more advanced control.

import asyncio
from src.foxglove2zmq import FoxgloveToZMQPushRelay, FoxgloveToZMQPubSubRelay


async def main():
    # Example for PUSH relay
    push_relay = FoxgloveToZMQPushRelay(
        foxglove_address="ws://localhost:8765",
        zmq_address="tcp://localhost:5555",
        zmq_listen_address="tcp://localhost:5556",
        topic_blocklist=["/diagnostics"],
        discovery_timeout=5.0
    )
    await push_relay.run()


if __name__ == "__main__":
    try:
        asyncio.run(main())
    except KeyboardInterrupt:
        print("Relay stopped by user.")

Library Example

You can find example scripts in the examples/ directory that demonstrate how to use the relay in different scenarios, including both PUSH/PULL and PUB/SUB patterns. First install the package, then run the examples:

  1. zmq_relay.py: A simple script to run the relay, must be run first. Defaults to PUSH/PULL mode on ZMQ bind tcp://localhost:5555.
  2. zmq_puller.py: A ZMQ PULL client that connects to the relay and prints received messages.
  3. zmq_subber.py: A ZMQ SUB client that connects to the relay and subscribes to all topics.
  4. zmq_pusher.py: A ZMQ PUSH client that sends messages to the relay, which will then be relayed to Foxglove.

Project Structure

foxglove2zmq/
├── src/
│   └── foxglove2zmq/
│       ├── __init__.py
│       ├── relay.py
│       └── cli.py
├── examples/
│   ├── zmq_puller.py
│   ├── zmq_pusher.py 
│   ├── zmq_relay.py
│   └── zmq_subber.py
├── LICENSE.md
├── pyproj.toml
├── README.md
└── requirements.txt  

License

This project is licensed under the MIT License; see the LICENSE file for details.

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

foxglove2zmq-0.1.2.tar.gz (13.9 kB view details)

Uploaded Source

Built Distribution

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

foxglove2zmq-0.1.2-py3-none-any.whl (12.3 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: foxglove2zmq-0.1.2.tar.gz
  • Upload date:
  • Size: 13.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.9.6

File hashes

Hashes for foxglove2zmq-0.1.2.tar.gz
Algorithm Hash digest
SHA256 a2f874f9eb6dfb09a65ebffd7f24a0536e6ceb6dd5327f3fa26fcef612a50915
MD5 c4169b5565d60f84845fef7982d595d8
BLAKE2b-256 1fb8a6c2b3423a94f93d80fde5dd9019cab19ad495637e789a680e6a424f8156

See more details on using hashes here.

File details

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

File metadata

  • Download URL: foxglove2zmq-0.1.2-py3-none-any.whl
  • Upload date:
  • Size: 12.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.9.6

File hashes

Hashes for foxglove2zmq-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 0cc4585774612bb98bebe642159df57040838e6a9de1afd4eaf52c2eccd18c44
MD5 99c422307cd01ee538689a0848600b24
BLAKE2b-256 035c390885f6706b1a0e33b4f6fd81045e6d30cf79a468abac12587148eea405

See more details on using hashes here.

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