aboutsummaryrefslogtreecommitdiffstats
path: root/Scripts/record_playback.py
diff options
context:
space:
mode:
Diffstat (limited to 'Scripts/record_playback.py')
-rw-r--r--Scripts/record_playback.py141
1 files changed, 141 insertions, 0 deletions
diff --git a/Scripts/record_playback.py b/Scripts/record_playback.py
new file mode 100644
index 0000000..e518356
--- /dev/null
+++ b/Scripts/record_playback.py
@@ -0,0 +1,141 @@
+# Copyright (C) 2024 Suchinton Chakravarty
+#
+# SPDX-License-Identifier: Apache-2.0
+
+import can
+import time
+from rich.console import Console
+import os
+import argparse
+
+class CAN_playback:
+ def __init__(self, interface='vcan0'):
+ """
+ Initialize the CAN Tool with the specified interface.
+
+ Args:
+ interface (str): The CAN interface name (default: 'vcan0')
+ """
+ self.console_mode = False
+ self.interface = interface
+ self.bus = can.interface.Bus(interface='socketcan', channel=self.interface, bitrate=500000)
+ self.output_file = os.path.join(os.path.dirname(__file__), 'can_messages.txt')
+
+ def write_to_file(self, messages):
+ """
+ Write captured CAN messages to a file.
+
+ Args:
+ messages (list): List of can.Message objects to write
+ """
+ with open(self.output_file, 'w') as file:
+ for msg in messages:
+ file.write(f"{msg.timestamp},{msg.arbitration_id},{msg.dlc},{','.join(map(lambda b: f'0x{b:02x}', msg.data))}\n")
+
+ def playback_messages(self):
+ if os.path.exists(self.output_file):
+ #console.print("Replaying captured messages...")
+ messages = []
+ with open(self.output_file, 'r') as file:
+ for line in file:
+ parts = line.strip().split(',', 3) # Split into at most 4 parts
+ timestamp, arbitration_id, dlc, data_str = parts
+ # Extract the data bytes, removing '0x' and splitting by ','
+ data_bytes = [int(byte, 16) for byte in data_str.split(',') if byte]
+
+ msg = can.Message(
+ timestamp=float(timestamp),
+ arbitration_id=int(arbitration_id, 0),
+ dlc=int(dlc),
+ data=data_bytes
+ )
+ messages.append(msg)
+ self.replay_messages(messages)
+
+ def stop(self):
+ self._running = False
+ if self.bus is not None:
+ self.bus.shutdown()
+
+ def replay_messages(self, messages):
+ """
+ Replay CAN messages on the specified bus.
+
+ Args:
+ messages (list): List of can.Message objects to replay
+ """
+ self._running = True
+ start_time = messages[0].timestamp
+ for msg in messages:
+ delay = msg.timestamp - start_time
+ self.bus.send(msg)
+ time.sleep(delay)
+ start_time = msg.timestamp
+ if self._running == False: return
+
+ def capture_can_messages(self):
+ """
+ Capture CAN messages from the specified bus.
+
+ Returns:
+ list: List of captured can.Message objects
+ """
+ messages = []
+
+ if self.console_mode:
+ console = Console()
+ console.print(f"Capturing CAN messages on {self.interface}. Press Ctrl+C to stop.")
+
+
+ try:
+ while True:
+ message = self.bus.recv()
+ if message is not None:
+ messages.append(message)
+ except KeyboardInterrupt:
+ console.print("Capture stopped.")
+
+ return messages
+
+def main():
+ from rich.console import Console
+ from rich.prompt import Prompt
+
+ parser = argparse.ArgumentParser(description='CAN Message Capture and Replay Tool')
+ parser.add_argument('--interface', '-i', type=str, default='vcan0', help='Specify the CAN interface (default: vcan0)')
+ args = parser.parse_args()
+
+ # Initialize the CAN Tool with the specified interface
+ can_tool = CAN_playback(interface=args.interface)
+ can_tool.console_mode = True
+
+ console = Console()
+ while True:
+ console.print("\n[bold]CAN Message Capture and Replay[/bold]")
+ console.print("1. Capture CAN messages")
+ console.print("2. Replay captured messages")
+ console.print("3. Exit")
+
+ choice = Prompt.ask("Enter your choice", choices=['1', '2', '3'])
+
+ if choice == '1':
+ messages = can_tool.capture_can_messages()
+ console.print(f"Captured {len(messages)} messages.")
+ can_tool.write_to_file(messages)
+ console.print(f"CAN messages written to {can_tool.output_file}")
+ elif choice == '2':
+ if os.path.exists(can_tool.output_file):
+ console.print("Replaying captured messages...")
+ can_tool.playback_messages()
+ console.print("Replay completed.")
+ else:
+ console.print(f"No captured messages found in {can_tool.output_file}")
+
+
+
+ else:
+ console.print("Exiting...")
+ break
+
+if __name__ == "__main__":
+ main()