-
Notifications
You must be signed in to change notification settings - Fork 16
/
lounge.yaml
136 lines (120 loc) · 4 KB
/
lounge.yaml
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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
substitutions:
roomname: lounge
static_ip: 10.0.0.14
yourname: Dale
rssi_present: id(harssi_present).state
rssi_not_present: id(harssi_not_present).state
esphome:
name: $roomname
platform: ESP32
board: wemos_d1_mini32
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
manual_ip:
static_ip: $static_ip
gateway: 10.0.0.1
subnet: 255.255.255.0
dns1: 10.0.0.1
ap:
ssid: ESPHome $roomname
password: !secret fallback_password
captive_portal:
logger:
#level: VERY_VERBOSE # If your Watch is not detected, uncomment and open Issue on GitHub with debug info
api:
ota:
mqtt:
broker: !secret mqtt_broker
username: !secret mqtt_username
password: !secret mqtt_password
discovery: false # Publish to MQTT, but not for Home Assistant (HA uses its own API)
esp32_ble_tracker:
scan_parameters:
interval: 1.2s
window: 500ms
active: false
on_ble_advertise:
- then:
# Look for manufacturer data of form: 4c00 10 05 YY 98 XXXXXX
# Where YY can be 01..0F or 20..2F; and XXXXXX is ignored
- lambda: |-
optional<int16_t> best_rssi = nullopt;
for (auto data : x.get_manufacturer_datas()) {
// Guard against non-Apple datagrams, or those that are too small.
if (data.data.size() < 4 || data.uuid.to_string() != "0x004C" || data.data[0] != 0x10 || data.data[1] < 5) {
continue;
}
const int16_t rssi = x.get_rssi();
const uint8_t status_flags = data.data[2] >> 4; // High nibble
const uint8_t data_flags = data.data[3];
if (data_flags == 0x98) { // Match unlocked Apple Watch. To also match locked watch use: if (data_flags == 0x98 || data_flags == 0x18) {
if (status_flags == 0 || status_flags == 2) {
best_rssi = max(rssi, best_rssi.value_or(rssi));
ESP_LOGD("ble_adv", "Found Apple Watch (mac %s) rssi %i", x.address_str().c_str(), rssi);
} else {
ESP_LOGD("ble_adv", "Possible Apple Watch? (mac %s) rssi %i, unrecognised status/action flags %#04x", x.address_str().c_str(), rssi, data.data[2]);
}
}
}
if (best_rssi) {
id(apple_watch_rssi).publish_state(*best_rssi);
}
sensor:
- platform: template
id: apple_watch_rssi
name: "$yourname Apple Watch $roomname RSSI"
device_class: signal_strength
unit_of_measurement: dBm
accuracy_decimals: 0
filters:
- exponential_moving_average:
alpha: 0.3
send_every: 1
on_value:
then:
- lambda: |-
if (id(apple_watch_rssi).state > $rssi_present) {
id(room_presence_debounce).publish_state(1);
} else if (id(apple_watch_rssi).state < $rssi_not_present) {
id(room_presence_debounce).publish_state(0);
}
- script.execute: presence_timeout # Publish 0 if no rssi received
- platform: template
id: room_presence_debounce
filters:
- sliding_window_moving_average:
window_size: 3
send_every: 1
- platform: homeassistant
name: HA RSSI Present Value
entity_id: input_number.rssi_present
id: harssi_present
internal: true
- platform: homeassistant
name: HA RSSI Not Present Value
entity_id: input_number.rssi_not_present
id: harssi_not_present
internal: true
binary_sensor:
- platform: template
id: room_presence
name: "$yourname $roomname presence"
device_class: occupancy
lambda: |-
if (id(room_presence_debounce).state > 0.99) {
return true;
} else if (id(room_presence_debounce).state < 0.01) {
return false;
} else {
return id(room_presence).state;
}
script:
# Publish event every 30 seconds when no rssi received
id: presence_timeout
mode: restart
then:
- delay: 30s
- lambda: |-
id(room_presence_debounce).publish_state(0);
- script.execute: presence_timeout