├── .gitignore ├── README.md └── tpms-helper /.gitignore: -------------------------------------------------------------------------------- 1 | /sample -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # tpms helper 2 | A bash shell script to partially automate Toyota tire pressure monitoring system testing via rtl_433. 3 | 4 | I created this script as a companion to the TPMS sensor testing process described in [this article](https://www.r-c-y.net/posts/tpms/). This script is a wrapper for rtl_433 that provides guidance for this process, error handling and simple, human-readable output. 5 | 6 | For more information on this script, [read this blog post](https://www.r-c-y.net/posts/tpmsbash/). 7 | 8 | ## Requirements 9 | - [bash shell](https://www.gnu.org/software/bash/), version 4.0 or later 10 | - [jq](https://stedolan.github.io/jq/) 11 | - [bc](https://www.gnu.org/software/bc/) 12 | - [rtl_433](https://github.com/merbanan/rtl_433) 13 | - SDR hardware compatible with rtl_433 14 | 15 | ## Installing and running 16 | ``` 17 | git clone https://github.com/rouyng/tpms-helper.git 18 | cd tpms-helper 19 | chmod +x tpms-helper 20 | ./tpms-helper 21 | ``` 22 | -------------------------------------------------------------------------------- /tpms-helper: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # TPMS Helper v1 3 | # Bash shell script to guide testing of Toyota PMV-107J TPMS sensors using rtl_433 4 | # Requires bash >4.0, rtl_433, jq, bc 5 | # for more information, see README.md 6 | 7 | # Minimum signal strength level for detection. 8 | # Decrease if no sensor is detected 9 | # Increase if multiple sensors are detected 10 | readonly MINLEVEL="-0.5" 11 | # Sensor type, default is 110 for Toyota's PMJ-107V. See rtl_433 docs for more options 12 | readonly SENSOR_TYPE="110" 13 | # Receive frequency to listen for signals, in Hz. Default is 315 MHz for Toyota sensors 14 | readonly RX_FREQ="315000000" 15 | # Time in seconds to listen for signals. 16 | # Default is 60, as Toyota sensors xmit every 60s. Other sensors may need more 17 | readonly DURATION="60" 18 | 19 | # define command to run rtl_433 20 | readonly RUNSDR="rtl_433 -M level -f ${RX_FREQ} -F json -T ${DURATION} -R ${SENSOR_TYPE} -Y minlevel=${MINLEVEL}" 21 | 22 | ############################### 23 | # Parse json-formatted output of a single signal decoded by rtl_433, set variables, and print details of the signal 24 | # Globals: 25 | # id 26 | # rssi 27 | # battery_status 28 | # Arguments: 29 | # String containing json representing one signal decoded by rtl_433 -F json 30 | ############################### 31 | parse_signal() { 32 | id="n/a" 33 | rssi="n/a" 34 | battery_status="n/a" 35 | id=$(echo "$1" | jq ".id") 36 | rssi=$(echo "$1" | jq ".rssi") 37 | if [[ $(echo "$1" | jq ".battery_ok") = 1 ]]; then 38 | battery_status="ok" 39 | elif [[ $(echo "$1" | jq ".battery_ok") = 0 ]]; then 40 | battery_status="\e[31mlow\e[0m" 41 | else 42 | battery_status="unknown" 43 | fi 44 | echo -e " └─Found sensor with ID ${id}, signal strength is ${rssi}, battery is ${battery_status}" 45 | } 46 | 47 | # declare an associative array for our formatted results, this also acts as a check for bash >4.0 48 | declare -A wheel_summaries 2> /dev/null || { echo -e "This script requires Bash >4.0, please update your bash version before running"; exit 1; } 49 | # checking for rtl_433 50 | rtl_433 -V > /dev/null 2>&1 || { echo -e "\e[31mrtl_433 was not found, please install it.\e[0m" >&2; exit 1; } 51 | # check for bc 52 | bc -v > /dev/null 2>&1 || { echo -e "\e[31mbc was not found, please install it.\e[0m" >&2; exit 1; } 53 | # check for jq 54 | jq --version > /dev/null 2>&1 || { echo -e "\e[31mjq was not found, please install it.\e[0m" >&2; exit 1; } 55 | 56 | wheels=("front left wheel" "back left wheel" "back right wheel" "front right wheel") 57 | too_many_signals=false 58 | for wheel in "${wheels[@]}"; do 59 | # prompt user to place sensor at appropriate wheel and wait for input 60 | echo -e "\e[33mPlease place antenna at ${wheel}" 61 | read -n 1 -s -r -p "Press any key to begin listening for signals" 62 | echo -e "\e[0m" 63 | # begin listening for sensor transmissions and save json output 64 | # to signals array 65 | echo -e "\e[32mRunning rtl_433, please wait...\e[0m" 66 | output=$($RUNSDR) || { echo -e "\e[31mCould not connect to RTL-SDR!\e[0m" >&2; exit 1; } 67 | mapfile -t signals < <( echo "${output}" | grep "{*}" ) 68 | if [[ ${#signals[@]} -gt 0 ]]; then 69 | echo -e "\e[32mReceived ${#signals[@]} signals from sensor(s) at ${wheel}.\e[0m" 70 | wheel_summary="" 71 | max_rssi=-99 72 | signal_descriptions=() 73 | for signal in "${signals[@]}"; do 74 | parse_signal "${signal}" 75 | # keep track of the max RSSI at each wheel 76 | # we use bc to compare rssi values because bash can't compare floating point numbers 77 | if [[ $(echo "${rssi}>${max_rssi}" | bc) == 1 ]]; then 78 | max_rssi="${rssi}" 79 | fi 80 | printf -v parsed_signal " └─ID: %s, RSSI: %s, Battery status: %s" "${id}" "${rssi}" "${battery_status}" 81 | signal_descriptions+=("${parsed_signal}") 82 | done 83 | for description in "${signal_descriptions[@]}"; do 84 | # if we have multiple signals at a wheel, we add a note to the one with the greatest RSSI 85 | if [[ ${#signals[@]} -gt 1 ]] && { echo "${description}" | grep -q -- "${max_rssi}"; }; then 86 | printf -v description "%s \e[1m<- strongest signal\e[0m" "${description}" 87 | too_many_signals=true # show a multiple signal warning in the summary 88 | fi 89 | wheel_summary+="${description}\n" 90 | done 91 | wheel_summaries["$wheel"]="${wheel_summary}" 92 | elif [[ ${#signals[@]} == 0 ]]; then 93 | echo -e "\e[31mReceived no signals at $wheel.\e[0m" 94 | wheel_summaries["$wheel"]=" └─\e[31mNONE! Sensor may be faulty or have a dead battery\e[0m" 95 | fi 96 | done 97 | 98 | # Now we print a nicely formatted summary of all detected sensors 99 | echo -e "\n\e[1mSummary of sensors detected\e[0m" 100 | for position in "${!wheel_summaries[@]}"; do 101 | echo -e "\e[1m${position}\e[0m" 102 | echo -e "${wheel_summaries[$position]}" 103 | done 104 | if $too_many_signals; then 105 | 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" 106 | fi 107 | --------------------------------------------------------------------------------