{"id":49151661,"url":"https://github.com/badgerloop-software/electrical-testbench","last_synced_at":"2026-04-22T06:11:37.755Z","repository":{"id":277079617,"uuid":"929943611","full_name":"badgerloop-software/electrical-testbench","owner":"badgerloop-software","description":"Application to sniff and spoof CAN messages using a Raspberry Pi","archived":false,"fork":false,"pushed_at":"2026-03-16T06:20:11.000Z","size":716,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"main","last_synced_at":"2026-03-16T18:31:13.203Z","etag":null,"topics":["can-bus","javascript","python","raspberry-pi"],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/badgerloop-software.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-02-09T18:53:54.000Z","updated_at":"2026-03-05T04:50:56.000Z","dependencies_parsed_at":"2025-02-12T02:41:54.997Z","dependency_job_id":"4c13e86a-b429-4f6c-9f2d-87b1de4fb705","html_url":"https://github.com/badgerloop-software/electrical-testbench","commit_stats":null,"previous_names":["badgerloop-software/can-snooper","badgerloop-software/electrical-testbench"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/badgerloop-software/electrical-testbench","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/badgerloop-software%2Felectrical-testbench","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/badgerloop-software%2Felectrical-testbench/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/badgerloop-software%2Felectrical-testbench/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/badgerloop-software%2Felectrical-testbench/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/badgerloop-software","download_url":"https://codeload.github.com/badgerloop-software/electrical-testbench/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/badgerloop-software%2Felectrical-testbench/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32123674,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-22T00:31:26.853Z","status":"online","status_checked_at":"2026-04-22T02:00:05.693Z","response_time":58,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["can-bus","javascript","python","raspberry-pi"],"created_at":"2026-04-22T06:11:36.190Z","updated_at":"2026-04-22T06:11:37.746Z","avatar_url":"https://github.com/badgerloop-software.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Solar Car 2 Electrical Testbench\n\nA web-based dashboard for testing and monitoring CAN bus signals in real-time. This system allows you to send and receive CAN messages through an intuitive frontend interface, running on a Raspberry Pi connected to the vehicle's CAN bus.\n\nThe dashboard uses a **unified TX/RX architecture** — just like a real CAN node, it transmits and receives simultaneously. Each signal has a per-signal direction dropdown (TX or RX). TX signals can be driven via random wave, CSV replay, or manual input. RX signals display live values from the bus. Any signal (TX or RX) can be plotted on the always-visible graph panel.\n\n**Primary Use Case**: Connect your laptop/desktop to the Raspberry Pi over Tailscale, run the backend on the Pi, and interact with the CAN bus through the web dashboard.\n\nLink to docs: https://www.waveshare.com/wiki/RS485_CAN_HAT#Install_Library\n\nCAN Messages: https://docs.google.com/spreadsheets/d/12O2UPdM_fqUVKd0IXZ638wb1obtBXQp11giv7swfWM4/edit?gid=575020774#gid=575020774\n\n## Features\n\n- **Unified TX/RX Dashboard**: No mode switching — transmit and receive simultaneously, just like a real CAN node\n- **Per-Signal Direction**: Each signal has a TX/RX dropdown — TX to inject onto the bus, RX to monitor from the bus\n- **TX Generation**: Drive TX signals via Random Wave, CSV Replay, or Manual Override\n- **Live Graphing**: Use each graph's **Choose Signals** menu to select any TX or RX signal to visualize its value over time\n- **Bi-directional WebSocket communication** between frontend and CAN bus\n- **BSR Red branding** with D-DIN font\n- **180+ signals** from format.json organized by subsystem\n\n## Screenshots\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"frontend/public/screenshots/Frontend_UI.png\" alt=\"Dashboard Screenshot\" width=\"900\"/\u003e\n\u003c/p\u003e\n\n## Architecture\n\n```\nLaptop/Desktop (Browser) \u003c--WebSocket--\u003e Raspberry Pi (Backend) \u003c--CAN--\u003e Vehicle CAN Bus\n  ↓ Tailscale VPN ↓\n```\n\n## Quick Start (Primary Workflow)\n\n### 1. Setup Raspberry Pi\n\n**On the Raspberry Pi:**\n\n```bash\n# Clone the repository\ngit clone \u003crepo-url\u003e\ncd electrical-testbench\n\n# Initialize submodules\ngit submodule update --init --recursive\n\n# Create and activate virtual environment\npython3 -m venv .venv\nsource .venv/bin/activate\n\n# Install Python dependencies\npip install python-can websockets\n\n# Ensure CAN interface is up (replace can0 with vcan0 for testing)\nsudo ip link set can0 up type can bitrate 500000\n```\n\n**Configure Tailscale:**\n\n```bash\n# Install Tailscale on Pi\ncurl -fsSL https://tailscale.com/install.sh | sh\nsudo tailscale up\n\n# Get Pi's Tailscale IP\ntailscale ip -4\n# Example output: 100.64.1.5\n```\n\n**Start the Backend:**\n\n```bash\npython api/main.py\n```\n\nThe WebSocket server will run on port 8765.\n\n### 2. Setup Your Laptop/Desktop\n\n**Install Tailscale:**\n\n- Download from https://tailscale.com/download\n- Login and connect to the same Tailnet as the Pi\n\n**Update Frontend Configuration:**\n\nEdit `frontend/src/App.jsx` and replace `localhost` with your Pi's Tailscale IP:\n\n```javascript\nconst websocket = new WebSocket(`ws://100.64.1.5:${server}`);\n```\n\n**Install and Run Frontend:**\n\n```bash\ncd frontend\nnpm install\nnpm run dev\n```\n\nOpen your browser to `http://localhost:5173`\n\n### 3. Use the Dashboard\n\n- By default all signals start as **RX** (passive monitoring)\n- Set individual signals (or entire categories) to **TX** to inject values onto the CAN bus\n- Choose a TX generation mode: **Random Wave** or **CSV Replay**, then click **Start**\n- When TX generation is stopped, TX signals show manual input controls for one-off sends\n- Check the **plot** checkbox on any signal to visualize it on the live graph panel\n\n## Project Structure\n\n```\nelectrical-testbench/\n├── api/                           # WebSocket server for CAN communication\n│   └── main.py                    # Backend server (runs on Pi)\n├── can_utils/                     # CAN utilities\n│   ├── data_classes.py           # Signal data structures\n│   ├── encode_signal.py          # Signal → CAN encoding\n│   ├── read_can_messages.py      # CAN → Signal parsing\n│   └── send_messages.py          # Manual CAN message sender\n├── frontend/                      # React dashboard\n│   ├── src/\n│   │   ├── App.jsx               # WebSocket connection manager\n│   │   ├── signalConfig.js       # Frontend signal definitions\n│   │   └── components/\n│   │       ├── Dashboard.jsx     # Main unified dashboard UI\n│   │       └── Graph.jsx         # Live signal graph component\n│   ├── public/fonts/             # D-DIN fonts\n│   └── package.json\n├── sc-data-format/              # Signal definitions (submodule)\n│   └── format.json               # CAN signal specifications\n├── d-din/                        # D-DIN font files\n└── README.md\n```\n## Testing Without CAN Hardware\n\nFor development and testing without real CAN hardware:\n\n**Create Virtual CAN Interface:**\n\n```bash\nsudo modprobe vcan\nsudo ip link add dev vcan0 type vcan\nsudo ip link set up vcan0\n```\n\n**Update Backend to Use vcan0:**\n\nIn `api/main.py`, change:\n```python\nbus = can.interface.Bus(channel=\"vcan0\", bustype=\"socketcan\")\n```\n\n**Monitor CAN Traffic:**\n\n```bash\ncandump vcan0\n```\n\n**Send Test Messages:**\n\nUse the included utility:\n```bash\npython can_utils/send_messages.py vcan0\n```\n\nOr send directly with Python:\n```python\nimport can, struct\nbus = can.interface.Bus(channel='vcan0', bustype='socketcan')\n# Send accelerator_pedal = 0.75 (CAN ID 0x200, offset 0)\ndata = struct.pack('\u003cf', 0.75) + b'\\x00'*4\nmsg = can.Message(arbitration_id=0x200, data=data, is_extended_id=False)\nbus.send(msg)\n```\n\n## Backup: Individual Python Scripts\n\nIf you need to interact with CAN directly without the dashboard:\n\n**Listen to CAN Messages (Console Output):**\n```bash\npython can_utils/read_can_messages.py\n```\n\n**Send CAN Messages Interactively:**\n```bash\npython can_utils/send_messages.py can0\n```\n\n**Mock Data Server (Testing):**\n```bash\npython mock_messages.py\n```\n\n## Troubleshooting\n\n**WebSocket connection fails:**\n- Check that backend is running: `python api/main.py`\n- Verify Tailscale IPs match in `frontend/src/App.jsx`\n- Check firewall: `sudo ufw allow 8765/tcp`\n\n**CAN messages not sending:**\n- Verify CAN interface is up: `ip link show can0`\n- Check permissions: may need `sudo` for CAN access\n- Test with `cansend` or `candump` utilities\n\n**Signals not encoding:**\n- Ensure signal name matches exactly in `sc-data-format/format.json`\n- Check backend logs for encoding errors\n\n**Numbers showing white instead of green:**\n- Backend must be parsing incoming messages correctly\n- Check that CAN IDs and offsets in `format.json` match transmitted messages\n- Verify WebSocket is receiving parsed data (check browser console)\n\n## Requirements\n\n- **Hardware**: Raspberry Pi with CAN HAT (e.g., Waveshare RS485 CAN HAT)\n- **Software**: \n  - Raspberry Pi OS (or Linux with SocketCAN)\n  - Python 3.7+\n  - Node.js 14+ (for frontend)\n  - Tailscale (for remote access)\n- **Network**: Tailscale VPN connecting laptop and Pi\n\n## Color Scheme\n\n- **BSR Red** (#A90515): Active buttons, category headers, progress bars (send mode)\n- **Green** (#10b981): Received signal values and progress bars (read mode)\n- **Black/White**: Background and text\n- **Font**: D-DIN\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbadgerloop-software%2Felectrical-testbench","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbadgerloop-software%2Felectrical-testbench","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbadgerloop-software%2Felectrical-testbench/lists"}