-
Notifications
You must be signed in to change notification settings - Fork 0
/
monitor.py
58 lines (47 loc) · 1.58 KB
/
monitor.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
import sys
import struct
from panda import Panda
CURRENT_SPEED = 0.0
BUTTON = 0
PRESS_COUNT = 0
def read_vehicle_speed(p: Panda) -> None:
"""Read the CAN messages and parse out the vehicle speed."""
global CURRENT_SPEED
global BUTTON
global PRESS_COUNT
for addr, _, dat, _src in p.can_recv():
if addr == 0x3e9: # Speed is 1001 (0x3e9 hex)
# '!' for big-endian. H for unsigned short (since it's 16 bits or 2 bytes)
# divide by 100.0 b/c factor is 0.01
CURRENT_SPEED = struct.unpack("!H", dat[:2])[0] / 100.0
elif addr == 0x1e1: # ASCMSteeringButton
# Check if the 7th bit of byte 4 is a 1
if int(dat[4]) >> 7 & 1:
print(f"Data (1): {dat}")
BUTTON = 1
elif BUTTON == 1:
# Increment the press count on button release
PRESS_COUNT += 1
BUTTON = 0
else:
BUTTON = 0
# Just keep updating the same line
sys.stdout.write(f"\rSpeed: {int(CURRENT_SPEED):03d} Button: {BUTTON}")
sys.stdout.flush()
def main() -> None:
"""Entry Point. Monitor Chevy volt speed."""
try:
p = Panda()
except Exception as exc:
print(f"Failed to connect to Panda! {exc}")
return
try:
while True:
read_vehicle_speed(p)
except KeyboardInterrupt:
print("Exiting...")
print("Press count: ", PRESS_COUNT) # Should be the same number of times we pressed it.
finally:
p.close()
if __name__ == "__main__":
main()