Skip to content

Commit 2f3e335

Browse files
committed
[feat] Auto MAC address detection
1 parent 8c104ba commit 2f3e335

File tree

6 files changed

+101
-41
lines changed

6 files changed

+101
-41
lines changed

CHANGELOG.md

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,24 @@
11
# Changelog
22

3-
## 0.1.1
3+
## 0.2.0
44

55
### Changed
66

7-
<p>WARNING WARNING WARNING<br>
8-
DO NOT UPGRADE PRIOR TO READ THE 0.1.0 UPGRADE INSTRUCTIONS<br>
9-
WARNING WARNING WARNING</p>
7+
<p>**WARNING WARNING WARNING**<br>
8+
Upgrading from 0.0.10 or previous? DO NOT UPGRADE PRIOR TO READ THE 0.1.0 UPGRADE INSTRUCTIONS.</p>
9+
10+
- NEW Feature: BLE MAC address auto-detection (unless presence detection is disable)
11+
- CHG: Removed setting ble\_mac\_list; obsoleted by mac-auto-detection
12+
13+
## 0.1.2
14+
15+
### Changed
16+
17+
- CHG: Fix allow empty setting BLE MAC addr (Docker standalone)
18+
19+
## 0.1.1
20+
21+
### Changed
1022

1123
- CHG: Fix upgrade forcing to redeploy the key to the car
1224

env.sh

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
#
33
# shellcheck shell=dash
44
#
5-
export SW_VERSION=0.1.1
5+
export SW_VERSION=0.2.0
66

77
### LOAD LIBRARIES (FUNCTIONS & ENVIRONMENT ) #################################
88
echo "[$(date +%H:%M:%S)] loading libproduct.sh"
@@ -34,14 +34,14 @@ export PRESENCE_DETECTION_LOOP_DELAY=${PRESENCE_DETECTION_LOOP_DELAY:-120}
3434
export PRESENCE_DETECTION_TTL=${PRESENCE_DETECTION_TTL:-240}
3535

3636
export BLE_LN_REGEX='S[0-9A-Fa-f]{16}C'
37+
export BLTCTL_COMMAND_DEVICES=false
3738
export KEYS_DIR=/share/tesla_ble_mqtt
38-
export MAC_REGEX='([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})'
39+
export MAC_REGEX='([0-9A-Fa-f]{2}[:]){5}([0-9A-Fa-f]{2})'
3940
export VIN_REGEX='[A-HJ-NPR-Z0-9]{17}'
4041

4142
### LOG CONFIG VARS ###########################################################
4243
log_info "Configuration Options are:
4344
BLE_CMD_RETRY_DELAY=$BLE_CMD_RETRY_DELAY
44-
BLE_MAC_LIST=$BLE_MAC_LIST
4545
DEBUG=$DEBUG
4646
MQTT_SERVER=$MQTT_SERVER
4747
MQTT_PORT=$MQTT_PORT

mqtt-discovery.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ function setupHADevicePanelCardsMain() {
4646
configHADeviceEnvVars $vin
4747

4848
# If detection is enable, show presence
49-
if [ $PRESENCE_DETECTION_TTL -gt 0 ] && [ -n "$BLE_MAC_LIST" ]; then
49+
if [ $PRESENCE_DETECTION_TTL -gt 0 ]; then
5050
log_debug "setupHADevicePanelCardsMain() vin:$vin presence detection enable"
5151
setupHADevicePresenceSensor $vin
5252
fi

run.sh

Lines changed: 25 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,28 @@ echo "[$(date +%H:%M:%S)] Starting... loading /app/env.sh"
1010
. /app/env.sh
1111

1212
# Replace | with ' ' white space
13-
BLE_MAC_LIST=$(echo $BLE_MAC_LIST | sed -e 's/[|,;]/ /g')
1413
VIN_LIST=$(echo $VIN_LIST | sed -e 's/[|,;]/ /g')
1514

1615
vin_count=0
1716
for vin in $VIN_LIST; do
1817
# Populate BLE Local Names list
1918
vin_count=$((vin_count + 1))
2019
BLE_LN=$(vinToBLEln $vin)
21-
log_debug "Adding $BLE_LN to BLE_LN_LIST, count $vin_count"
20+
log_debug "Adding $BLE_LN to BLE_LN_LIST, vin_count:$vin_count"
2221
BLE_LN_LIST="$BLE_LN_LIST $BLE_LN"
22+
if [ -f $KEYS_DIR/${vin}_macaddr ]; then
23+
BLE_MAC=$(cat $KEYS_DIR/${vin}_macaddr)
24+
log_debug "Found BLE_MAC:$BLE_MAC in $KEYS_DIR/${vin}_macaddr; adding to BLE_MAC_LIST"
25+
BLE_MAC_LIST="$BLE_MAC_LIST $BLE_MAC"
26+
else
27+
log_debug "Adding default value FF:FF:FF:FF:FF:FF to BLE_MAC_LIST"
28+
BLE_MAC_LIST="$BLE_MAC_LIST FF:FF:FF:FF:FF:FF"
29+
# Request bluetooth_read to run the "devices" command
30+
# shellcheck disable=SC2034
31+
BLTCTL_COMMAND_DEVICES=true
32+
fi
33+
log_debug "Adding default value 0 to PRESENCE_EXPIRE_TIME_LIST"
34+
PRESENCE_EXPIRE_TIME_LIST="$PRESENCE_EXPIRE_TIME_LIST 0"
2335

2436
if [ -f $KEYS_DIR/${vin}_private.pem ] &&
2537
[ -f $KEYS_DIR/${vin}_public.pem ]; then
@@ -41,20 +53,17 @@ for vin in $VIN_LIST; do
4153
delete_legacies $vin
4254
fi # END TEMPORARY
4355
done
56+
# remove leading white space
57+
BLE_LN_LIST=$(echo $BLE_LN_LIST | sed -e 's/^ //g')
58+
BLE_MAC_LIST=$(echo $BLE_MAC_LIST | sed -e 's/^ //g')
59+
PRESENCE_EXPIRE_TIME_LIST=$(echo $PRESENCE_EXPIRE_TIME_LIST | sed -e 's/^ //g')
4460

45-
# Populate PRESENCE_EXPIRE_TIME_LIST only if Presence Detection is enable
46-
if [ $PRESENCE_DETECTION_TTL -gt 0 ]; then
47-
log_info "Presence detection is enable with a TTL of $PRESENCE_DETECTION_TTL seconds"
48-
ble_mac_addr_count=0
49-
# shellcheck disable=SC2034
50-
for ble_mac in $BLE_MAC_LIST; do
51-
ble_mac_addr_count=$((ble_mac_addr_count + 1))
52-
log_debug "Adding 0 to PRESENCE_EXPIRE_TIME_LIST, count $ble_mac_addr_count"
53-
PRESENCE_EXPIRE_TIME_LIST="$PRESENCE_EXPIRE_TIME_LIST 0"
54-
done
55-
else
56-
log_info "Presence detection is not enabled due to TTL of $PRESENCE_DETECTION_TTL seconds"
57-
fi
61+
# log _LIST values
62+
log_debug "VIN_LIST:$VIN_LIST"
63+
log_debug "BLE_LN:$BLE_LN"
64+
log_debug "BLE_LN_LIST:$BLE_LN_LIST"
65+
log_debug "BLE_MAC_LIST:$BLE_MAC_LIST"
66+
log_debug "PRESENCE_EXPIRE_TIME_LIST:$PRESENCE_EXPIRE_TIME_LIST"
5867

5968
# Setup HA auto discovery, or skip if HA backend is disable, and discard old MQTT messages
6069
discardMessages=yes
@@ -79,7 +88,7 @@ while :; do
7988
# Don't run presence detection if TTL is 0
8089

8190
# If PRESENCE_DETECTION_TTL > 0 and BLE_MAC_LIST is not empty
82-
if [ $PRESENCE_DETECTION_TTL -gt 0 ] && [ -n "$BLE_MAC_LIST" ]; then
91+
if [ $PRESENCE_DETECTION_TTL -gt 0 ]; then
8392
log_info "Launch BLE scanning for car presence every $PRESENCE_DETECTION_LOOP_DELAY seconds"
8493
listen_to_ble $vin_count
8594
# Run listen_to_ble every 3m

subroutines.sh

Lines changed: 55 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -34,16 +34,29 @@ replace_value_at_position() {
3434

3535
# Function
3636
check_presence() {
37-
TYPE="$1" # BLE MAC, LN
38-
MATCH="$2"
37+
BLE_LN="$1"
38+
BLE_MAC="$1"
3939

4040
CURRENT_TIME_EPOCH=$(date +%s)
41+
MATCH="($BLE_LN|$BLE_MAC)"
42+
43+
if [ $BLE_MAC == "FF:FF:FF:FF:FF:FF" ]; then
44+
log_debug "check_presence; looking BLE_MAC for BLE_LN:$BLE_LN"
45+
if grepOutput=$(echo "${BLTCTL_OUT}" | grep $BLE_LN | tail -1); then
46+
BLE_MAC=$(echo $grepOutput | grep -Eo $MAC_REGEX)
47+
log_info "check_presence; found BLE MAC addr:$BLE_MAC for BLE_LN:$BLE_LN"
48+
else
49+
log_debug "check_presence; did not find BLE MAC addr for BLE_LN:$BLE_LN"
50+
fi
51+
fi
52+
# return value to calling function
53+
echo $BLE_MAC
4154

4255
if echo "${BLTCTL_OUT}" | grep -Eq "$MATCH"; then
43-
log_info "VIN $VIN $TYPE $MATCH presence detected"
56+
log_info "vin:$VIN ble_ln:$BLE_LN match:$MATCH presence detected"
4457

4558
if [ $CURRENT_TIME_EPOCH -ge $PRESENCE_EXPIRE_TIME ]; then
46-
log_info "VIN $VIN $MATCH TTL expired, set presence ON"
59+
log_info "vin:$VIN ble_ln:$BLE_LN TTL expired, set presence ON"
4760
set +e
4861
# We need a function for mosquitto_pub w/ retry
4962
MQTT_OUT=$(eval $MOSQUITTO_PUB_BASE --nodelay -t "$MQTT_TOPIC" -m ON 2>&1)
@@ -57,14 +70,14 @@ check_presence() {
5770

5871
# Update presence expire time
5972
EPOCH_EXPIRE_TIME=$((CURRENT_TIME_EPOCH + PRESENCE_DETECTION_TTL))
60-
log_debug "VIN $VIN $MATCH update presence expire time to $EPOCH_EXPIRE_TIME"
73+
log_debug "vin:$VIN ble_ln:$BLE_LN update presence expire time to $EPOCH_EXPIRE_TIME"
6174
PRESENCE_EXPIRE_TIME_LIST=$(replace_value_at_position "$PRESENCE_EXPIRE_TIME_LIST" \
6275
$position $EPOCH_EXPIRE_TIME)
6376
# END if MATCH
6477
else
65-
log_debug "VIN $VIN $TYPE $MATCH presence not detected"
78+
log_debug "vin:$VIN ble_ln:$BLE_LN match:$MATCH presence not detected"
6679
if [ $CURRENT_TIME_EPOCH -ge $PRESENCE_EXPIRE_TIME ]; then
67-
log_info "VIN $VIN $TYPE $MATCH presence has expired, setting presence OFF"
80+
log_info "vin:$VIN ble_ln:$BLE_LN presence has expired, setting presence OFF"
6881
set +e
6982
MQTT_OUT=$(eval $MOSQUITTO_PUB_BASE --nodelay -t "$MQTT_TOPIC" -m OFF 2>&1)
7083
EXIT_STATUS=$?
@@ -74,7 +87,7 @@ check_presence() {
7487
return
7588
log_debug "mqtt topic $MQTT_TOPIC succesfully updated to OFF"
7689
else
77-
log_info "VIN $VIN $TYPE $MATCH presence not expired"
90+
log_info "vin:$VIN ble_ln:$BLE_LN presence not expired"
7891
fi # END if expired time
7992
fi # END if ! MATCH
8093
}
@@ -85,9 +98,26 @@ bluetoothctl_read() {
8598
# Read BLE data from bluetoothctl or an input file
8699
if [ -z $BLECTL_FILE_INPUT ]; then
87100
log_debug "Launching bluetoothctl to check for BLE presence"
88-
BLECTL_TIMEOUT=11
89101
set +e
90-
BLTCTL_OUT=$(bluetoothctl --timeout $BLECTL_TIMEOUT scan on 2>&1 | grep -v DEL)
102+
BLTCTL_OUT=$({
103+
if [ $BLTCTL_COMMAND_DEVICES == "true" ]; then
104+
bltctlCommands="power on,devices,scan on"
105+
else
106+
bltctlCommands="power on,scan on"
107+
fi
108+
IFS=','
109+
for bltctlCommand in $bltctlCommands; do
110+
echo "$bltctlCommand"
111+
sleep 0.2
112+
done
113+
114+
# scan for 10 seconds (Tesla adverstisement each ~9s)
115+
sleep 10
116+
117+
echo "scan off"
118+
echo "power off"
119+
echo "exit"
120+
} | bluetoothctl)
91121
set -e
92122
else
93123
# Read from file, great for testing w/ no Bluetooth adapter
@@ -119,6 +149,7 @@ listen_to_ble() {
119149
while :; do
120150
bluetoothctl_read
121151

152+
BLTCTL_COMMAND_DEVICES=false
122153
for position in $(seq $n_vins); do
123154
set -- $BLE_LN_LIST
124155
BLE_LN=$(eval "echo \$${position}")
@@ -132,8 +163,18 @@ listen_to_ble() {
132163
MQTT_TOPIC="tesla_ble/$VIN/binary_sensor/presence"
133164

134165
# Check the presence using both MAC Addr and BLE Local Name
135-
log_debug "$(echo "$BLTCTL_OUT" | grep -E "($BLE_MAC|$BLE_LN)")"
136-
check_presence "BLE MAC & LN" "($BLE_MAC|$BLE_LN)"
166+
log_debug "BLTCTL_OUT:$(echo "$BLTCTL_OUT" | grep -E "($BLE_MAC|$BLE_LN)")"
167+
macAddr=$(check_presence $BLE_LN $BLE_MAC)
168+
169+
# Add the MAC address to BLE_MAC_LIST if it's not already present at the position
170+
if [ "$macAddr" != "$BLE_MAC" ]; then
171+
eval "BLE_MAC_LIST=\$(echo \$BLE_MAC_LIST | awk '{\$${position}=\"$macAddr\"; print}')"
172+
log_debug "listen_to_ble; BLE_MAC_LIST:$BLE_MAC_LIST"
173+
[ ! -f $KEYS_DIR/${VIN}_macaddr ] && echo $macAddr >$KEYS_DIR/${VIN}_macaddr
174+
fi
175+
176+
# If a MAC addr is unknown, request "bltctl devices"
177+
[ $macAddr == "FF:FF:FF:FF:FF:FF" ] && BLTCTL_COMMAND_DEVICES=true
137178

138179
done
139180
sleep $PRESENCE_DETECTION_LOOP_DELAY
@@ -151,16 +192,14 @@ scanBLEforMACaddr() {
151192
# quite old, but has the principles for auto populating the BLE MAC Address with only the VIN
152193
vin=$1
153194

154-
mac_regex='([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})'
155-
156195
ble_ln=$(vinToBLEln $vin)
157196

158197
log_info "Looking for vin:$vin in the BLE cache that matches ble_ln:$ble_ln"
159-
if ! bltctl_out=$(bluetoothctl --timeout 2 devices | grep $ble_ln | grep -Eo $mac_regex); then
198+
if ! bltctl_out=$(bluetoothctl --timeout 2 devices | grep $ble_ln | grep -Eo $MAC_REGEX); then
160199
log_notice "Couldn't find a match in the cache for ble_ln:$ble_ln for vin:$vin"
161200
# Look for a BLE adverstisement matching ble_ln
162201
log_notice "Scanning (10 seconds) for BLE advertisement that matches ble_ln:$ble_ln vin:$vin"
163-
if ! bltctl_out=$(bluetoothctl --timeout 10 scan on | grep $ble_ln | grep -Eo $mac_regex); then
202+
if ! bltctl_out=$(bluetoothctl --timeout 10 scan on | grep $ble_ln | grep -Eo $MAC_REGEX); then
164203
log_notice "Couldn't find a BLE advertisement for ble_ln:$ble_ln vin:$vin"
165204
return 1
166205
fi

version.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@
22
#
33
# shellcheck shell=dash
44
#
5-
export SW_VERSION=0.1.1
5+
export SW_VERSION=0.2.0

0 commit comments

Comments
 (0)