Datalogging

Every pyCANdo device runs a time-series database optimized for CAN bus data built on Apache Datafusion. Incoming traffic is retained independently of the logging configured in your Python code, so a missed trigger does not have to mean a lost frame.

./rbs/main.py
Copy code
from pyrbs import PyRbs, CanMessage, CanSignal, Timer, BusLoggerfrom datetime import datetime as dtnow = dt.now().strftime('%Y-%m-%d_%H-%M-%S')rbs = PyRbs()full_trace: BusLogger = rbs.buslog.add("full_trace", f"examples/can_trace_{now}.mf4")timer_100ms: Timer = rbs.timer.add("timer_100ms", 0.1, active_on_start=True)msg_heartbeat: CanMessage = rbs.can_message.get("CAN1.HeartBeat")@rbs.on_start()def on_start():    full_trace.start()@rbs.on_stop()def on_stop():    full_trace.stop()@rbs.timer.on("timer_100ms")def on_timer_100ms(self: Timer):    msg_heartbeat.send()# Create a snapshot when Status_01.Error changes to 1.@rbs.can_signal.on_change("CAN1.Status_01.Error")def on_status_error(self: CanSignal):    if self.raw == 1:        trigger_time = dt.now().strftime('%Y-%m-%d_%H-%M-%S_%f')        rbs.buslog.snapshot(            "status_error",            f"examples/status_error_{trigger_time}.mf4",            pre_trigger=180,  # Three minutes before the error.            post_trigger=180,  # Three minutes after the error.        )

Define traces with the BusLogger class

Use the BusLogger class to export data from the device database into the file format your analysis workflow needs. Export processing runs independently, so creating a file does not influence simulation performance.

Logging triggers and snapshots are lightweight metadata. You can also create an individual CAN trace later from the control dashboard after an unplanned power interruption or a missing trigger.

Snapshot trigger

Alongside classic start-and-stop logging, a snapshot can include a configurable number of seconds before and after the trigger. Place the trigger directly in the restbus code to capture the context around an event.

This example uses a fictional Status_01 message with an Error signal: 0 means OK and 1 means fault. When the signal changes to 1, the callback captures three minutes before and three minutes after the error. Repeated frames with the same error value do not create additional snapshots.

./rbs/main.py
Copy code
from pyrbs import PyRbs, CanSignalfrom datetime import datetime as dtrbs = PyRbs()# Create a snapshot when Status_01.Error changes to 1.@rbs.can_signal.on_change("CAN1.Status_01.Error")def on_status_error(self: CanSignal):    if self.raw == 1:        trigger_time = dt.now().strftime('%Y-%m-%d_%H-%M-%S_%f')        rbs.buslog.snapshot(            "status_error",            f"examples/status_error_{trigger_time}.mf4",            pre_trigger=180,  # Three minutes before the error.            post_trigger=180,  # Three minutes after the error.        )

Download trace files

Browse the traces available on the device and download them through the web browser. A network-drive connection can also expose the same files directly in Windows File Explorer.

pyCANdo Traces panel with a trace file context menu showing the download action