-
Notifications
You must be signed in to change notification settings - Fork 4
/
tpms-helper
executable file
·106 lines (100 loc) · 4.8 KB
/
tpms-helper
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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
#!/bin/bash
# TPMS Helper v1
# Bash shell script to guide testing of Toyota PMV-107J TPMS sensors using rtl_433
# Requires bash >4.0, rtl_433, jq, bc
# for more information, see README.md
# Minimum signal strength level for detection.
# Decrease if no sensor is detected
# Increase if multiple sensors are detected
readonly MINLEVEL="-0.5"
# Sensor type, default is 110 for Toyota's PMJ-107V. See rtl_433 docs for more options
readonly SENSOR_TYPE="110"
# Receive frequency to listen for signals, in Hz. Default is 315 MHz for Toyota sensors
readonly RX_FREQ="315000000"
# Time in seconds to listen for signals.
# Default is 60, as Toyota sensors xmit every 60s. Other sensors may need more
readonly DURATION="60"
# define command to run rtl_433
readonly RUNSDR="rtl_433 -M level -f ${RX_FREQ} -F json -T ${DURATION} -R ${SENSOR_TYPE} -Y minlevel=${MINLEVEL}"
###############################
# Parse json-formatted output of a single signal decoded by rtl_433, set variables, and print details of the signal
# Globals:
# id
# rssi
# battery_status
# Arguments:
# String containing json representing one signal decoded by rtl_433 -F json
###############################
parse_signal() {
id="n/a"
rssi="n/a"
battery_status="n/a"
id=$(echo "$1" | jq ".id")
rssi=$(echo "$1" | jq ".rssi")
if [[ $(echo "$1" | jq ".battery_ok") = 1 ]]; then
battery_status="ok"
elif [[ $(echo "$1" | jq ".battery_ok") = 0 ]]; then
battery_status="\e[31mlow\e[0m"
else
battery_status="unknown"
fi
echo -e " └─Found sensor with ID ${id}, signal strength is ${rssi}, battery is ${battery_status}"
}
# declare an associative array for our formatted results, this also acts as a check for bash >4.0
declare -A wheel_summaries 2> /dev/null || { echo -e "This script requires Bash >4.0, please update your bash version before running"; exit 1; }
# checking for rtl_433
rtl_433 -V > /dev/null 2>&1 || { echo -e "\e[31mrtl_433 was not found, please install it.\e[0m" >&2; exit 1; }
# check for bc
bc -v > /dev/null 2>&1 || { echo -e "\e[31mbc was not found, please install it.\e[0m" >&2; exit 1; }
# check for jq
jq --version > /dev/null 2>&1 || { echo -e "\e[31mjq was not found, please install it.\e[0m" >&2; exit 1; }
wheels=("front left wheel" "back left wheel" "back right wheel" "front right wheel")
too_many_signals=false
for wheel in "${wheels[@]}"; do
# prompt user to place sensor at appropriate wheel and wait for input
echo -e "\e[33mPlease place antenna at ${wheel}"
read -n 1 -s -r -p "Press any key to begin listening for signals"
echo -e "\e[0m"
# begin listening for sensor transmissions and save json output
# to signals array
echo -e "\e[32mRunning rtl_433, please wait...\e[0m"
output=$($RUNSDR) || { echo -e "\e[31mCould not connect to RTL-SDR!\e[0m" >&2; exit 1; }
mapfile -t signals < <( echo "${output}" | grep "{*}" )
if [[ ${#signals[@]} -gt 0 ]]; then
echo -e "\e[32mReceived ${#signals[@]} signals from sensor(s) at ${wheel}.\e[0m"
wheel_summary=""
max_rssi=-99
signal_descriptions=()
for signal in "${signals[@]}"; do
parse_signal "${signal}"
# keep track of the max RSSI at each wheel
# we use bc to compare rssi values because bash can't compare floating point numbers
if [[ $(echo "${rssi}>${max_rssi}" | bc) == 1 ]]; then
max_rssi="${rssi}"
fi
printf -v parsed_signal " └─ID: %s, RSSI: %s, Battery status: %s" "${id}" "${rssi}" "${battery_status}"
signal_descriptions+=("${parsed_signal}")
done
for description in "${signal_descriptions[@]}"; do
# if we have multiple signals at a wheel, we add a note to the one with the greatest RSSI
if [[ ${#signals[@]} -gt 1 ]] && { echo "${description}" | grep -q -- "${max_rssi}"; }; then
printf -v description "%s \e[1m<- strongest signal\e[0m" "${description}"
too_many_signals=true # show a multiple signal warning in the summary
fi
wheel_summary+="${description}\n"
done
wheel_summaries["$wheel"]="${wheel_summary}"
elif [[ ${#signals[@]} == 0 ]]; then
echo -e "\e[31mReceived no signals at $wheel.\e[0m"
wheel_summaries["$wheel"]=" └─\e[31mNONE! Sensor may be faulty or have a dead battery\e[0m"
fi
done
# Now we print a nicely formatted summary of all detected sensors
echo -e "\n\e[1mSummary of sensors detected\e[0m"
for position in "${!wheel_summaries[@]}"; do
echo -e "\e[1m${position}\e[0m"
echo -e "${wheel_summaries[$position]}"
done
if $too_many_signals; then
echo -e "\e[33mWarning: Received more than one signal at a wheel. Consider increasing the MINLEVEL from the current value of ${MINLEVEL}, to filter adjacent sensors\e[0m"
fi