Skip to content

Commit cf7ef5e

Browse files
authored
Merge pull request #49 from Western-Formula-Racing/kvaser-bridge
Kvaser websocket bridge
2 parents 2db888b + aa4f98b commit cf7ef5e

13 files changed

Lines changed: 940 additions & 14 deletions

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,3 +238,4 @@ test-logs/
238238
# Ignore generated service worker files
239239
sw.js
240240
pecan/src/assets/WFR25.dbc
241+
WFR25.dbc

kvaser-bridge/README.md

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
# Kvaser Bridge
2+
3+
A GUI app that bridges a Kvaser CAN adapter to the DAQ Radio dashboard via WebSocket.
4+
5+
```
6+
Kvaser hardware
7+
| (python-can / Kvaser CANlib)
8+
v
9+
kvaser-bridge (this app)
10+
| JSON over WebSocket
11+
v
12+
DAQ Radio pecan dashboard
13+
```
14+
15+
## Prerequisites
16+
17+
- Python 3.10+
18+
- [Kvaser CANlib SDK](https://kvaser.com/download/)
19+
- tkinter (included with most Python installations)
20+
21+
## Install
22+
23+
```bash
24+
pip install -r requirements.txt
25+
```
26+
27+
## Run
28+
29+
```bash
30+
python src/main.py
31+
```
32+
33+
A small window appears with:
34+
- **Channel** - select which Kvaser CAN channel to use
35+
- **Bitrate** - CAN bus bitrate (default 500k)
36+
- **WS URL** - WebSocket URL of the dashboard (default `ws://localhost:9080`)
37+
- **Start/Stop Bridge** - toggle the connection
38+
39+
Click **Start Bridge** to begin streaming CAN frames to the dashboard.
40+
41+
## Build (standalone binary)
42+
43+
```bash
44+
# Linux
45+
pyinstaller build.spec
46+
47+
# Windows
48+
pyinstaller build.spec
49+
```
50+
51+
Output binary is in `dist/kvaser-bridge` (or `dist/kvaser-bridge.exe`).
52+
53+
## Architecture
54+
55+
| File | Purpose |
56+
|------|---------|
57+
| `src/main.py` | Entry point; starts asyncio loop + tkinter GUI |
58+
| `src/bridge.py` | Core Kvaser CAN -> WebSocket bridge (asyncio) |
59+
| `src/tray.py` | tkinter GUI window |
60+
| `src/config.py` | Bitrate options, defaults, config persistence |

kvaser-bridge/requirements.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
python-can==4.4.2
2+
websockets>=12.0
3+
pyinstaller>=6.0.0

kvaser-bridge/src/__init__.py

Whitespace-only changes.

kvaser-bridge/src/bridge.crt

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
-----BEGIN CERTIFICATE-----
2+
MIIDIjCCAgqgAwIBAgIUMQ/VVeq2vQtJinFyemCRrCo64yIwDQYJKoZIhvcNAQEL
3+
BQAwGDEWMBQGA1UEAwwNa3Zhc2VyLWJyaWRnZTAeFw0yNjAzMTIxODExNTdaFw0z
4+
NjAzMDkxODExNTdaMBgxFjAUBgNVBAMMDWt2YXNlci1icmlkZ2UwggEiMA0GCSqG
5+
SIb3DQEBAQUAA4IBDwAwggEKAoIBAQCfuil0T8evblomXFgg/Nsa4sDCbeN01kgm
6+
o6uuRbyeCpUl6jGvSp97cDovaEUs1v9w2fKSdQT/AIwrPuL+GCgPQIIoHXaOcEwL
7+
FXx8vXhJhWpdNVF1WQz2Gxo8xHWE1j78huF1HMpZMWq+f0rXrrGGcaXdx9o/JVMH
8+
YXBAcrf3rSbti1/JL35HWai5jbnXoA1lEbk/yae3YNieATpHiTln/+lr+QhS3ZoZ
9+
pex1qyeelpdriiLU59/4F/jOO3dce6dOwHuP8LnN9HsMitRQQYKnddb6YHehWMCZ
10+
BS+//ckTiqTk0BwFCk2eSHOsalM9ccK6hnQLuC2A0JS4Rq2FBj93AgMBAAGjZDBi
11+
MB0GA1UdDgQWBBRza55pGEyxq23W6qj46HQBkvb7IjAfBgNVHSMEGDAWgBRza55p
12+
GEyxq23W6qj46HQBkvb7IjAPBgNVHRMBAf8EBTADAQH/MA8GA1UdEQQIMAaHBH8A
13+
AAEwDQYJKoZIhvcNAQELBQADggEBADXgQghVupLiZQvAVDqcZbI7kDDqpR5MqK4r
14+
C3j04olmXOUIwx3LAdmqVcmERfNasfmWZadH5fU5I2EeQpITYT11h8UHctf8Pgju
15+
4x6GRGb3xgjrHp2v1RaNU7Svj33BrM2WlRPuJrjQEXKRamON5GB4XlPvs4HzSTe9
16+
1uN2hq+57tEOsqlvy14tONzo7SNDPS1r7k+rbTxPWs2vxuVPjW6MsCQ4dSN/mMhZ
17+
c+yCIMnC6Zt3IpX19+Xm/IJBvKUD2JnLsxUBYPvn5wpXiAsHXXI2nj9uFeeV59DO
18+
e0uufI0a5i2hDn0y2PTUWL86pf0ul0NdY36U+FS0V1M2jMh3MNM=
19+
-----END CERTIFICATE-----

kvaser-bridge/src/bridge.key

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
-----BEGIN PRIVATE KEY-----
2+
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCfuil0T8evblom
3+
XFgg/Nsa4sDCbeN01kgmo6uuRbyeCpUl6jGvSp97cDovaEUs1v9w2fKSdQT/AIwr
4+
PuL+GCgPQIIoHXaOcEwLFXx8vXhJhWpdNVF1WQz2Gxo8xHWE1j78huF1HMpZMWq+
5+
f0rXrrGGcaXdx9o/JVMHYXBAcrf3rSbti1/JL35HWai5jbnXoA1lEbk/yae3YNie
6+
ATpHiTln/+lr+QhS3ZoZpex1qyeelpdriiLU59/4F/jOO3dce6dOwHuP8LnN9HsM
7+
itRQQYKnddb6YHehWMCZBS+//ckTiqTk0BwFCk2eSHOsalM9ccK6hnQLuC2A0JS4
8+
Rq2FBj93AgMBAAECggEAFQPKuXVXqeKkdMCYjbqG30ovH0WS9AfPVVoaV+Lv9oEg
9+
72yZHd19DyIMXbljxIsC76eVLSS9RAmf536uIc0u1BbiKQH7W7E1qA2rI8RP46hs
10+
fpfpwD03odeeA5m7dn8zqUjbt+tSShrg1vBreeYPkEc6kevd8InqGyH8QVZ2ktzd
11+
XH3EeBIdMPkot+diEqvz+G9ZIggEiumA4vUTKHvoJGfrhuxkiVwzlRUzEaHTOjOP
12+
XZISeYlPNK8k4fjN/yoHGn7KXHCZE/QG9Hw5xRHaDC0txwqwCaNgQZaiMEmjtb89
13+
dN8PyTtupbe6wnTACbbdKPZmAkkMOK/1uXWmAwfNCQKBgQDXvOiEoR1B7gVZOwJR
14+
/e0ncIK0Wy46Maf+ioqJds/AZBFwflJb3tlYIL4R2qCqdNUv+9pbIgRwVKazPobK
15+
Ra+s67buKfFSvr5istfbkZ8i8WStdkW6BHOZuzpvtgVtO2xH88Tlxh0uVWsJQhUR
16+
8vzNSYYSAVbO1wFh1e1IoJBwGQKBgQC9iUk1gd2O7a2+yNcV566S/Zb5VRjhNeok
17+
kZ3ZGkOdjd5LHyVzO8bzNjTowf9BaWMQFcmyqQ18BO7qtQzIDFwwK1AR3gjbtYAk
18+
5NmEKLZSaMrusa3lSJf2KU+puru3rZMcrL3wilTvoMt4CZaxA7WF24qejsPsvJj8
19+
5U6eGWreDwKBgQCjv+99PA1JDbFhmTiZo3NujCepXcwov6gTvHSLAnOORGY4TKmW
20+
sf+mtLOQObHZr/RhB3kl0xwrZxVg2ATXYy2EwyWGgK97buxzXewZ7N4tV6xjPXKP
21+
TvGvrj0crbxQvNnjg1PgVA+yK4Oi81Wq2hSofTYWVI3fUbLq38XLapQ3gQKBgHaR
22+
eZDViuqs2TIupg73/ofJyDZ1+7h3Z+A0kBCOk5nudA9+jokF7jGbyYGKSsp6yRP4
23+
7VKs2tiopWWCmVpUER+5GL/0rIn1gxKRb1lztorbL4ge8vAqd5Xwxfsh6+i91vfr
24+
QG9HulalumN/bBuUfGweqRsDqKFiYjpioMnakLYVAoGBAItVpxs/wZHgtNJe1Hih
25+
IoCSRcSdLmwmFw+9V2DnmmxoH5yPYeoKR/rXCqngOgDD9/S6qnDYhFJx5yr+qsvW
26+
JWt0mMg4kSa1gVImMKuSrP6G42v7EVSJe1kOFcQl1Zm2d7RY3UY8LKeprm3ivnSB
27+
nd8KDUOdMZVS+0InTZeddQbJ
28+
-----END PRIVATE KEY-----

0 commit comments

Comments
 (0)