@@ -26,10 +26,15 @@ class BTHome:
26
26
# Device name used in BLE advertisements.
27
27
_local_name = ""
28
28
29
- # Naming convention is:
29
+ # For most sensors, naming convention is:
30
30
# <const_name> ::= <property> "_" <data-type> "_x" <inverse of factor>
31
- # For example , temperature sint16 0.01 becomes:
31
+ # Example , temperature sint16 0.01 becomes:
32
32
# TEMPERATURE _ SINT16 _x 100
33
+ # For binary sensors (0x15 .. 0x2D), naming convention is:
34
+ # <const_name> ::= <property> "_" BINARY
35
+ # Example, "battery charging" becomes:
36
+ # BATTERY_CHARGING_BINARY
37
+ # All binary sensors are packed as 8-bit unsigned bytes.
33
38
# See "Sensor Data" table at https://bthome.io/format/
34
39
BATTERY_UINT8_X1 = const (0x01 ) # %
35
40
TEMPERATURE_SINT16_X100 = const (0x02 ) # °C
@@ -45,9 +50,19 @@ class BTHome:
45
50
VOLTAGE_UINT16_X1000 = const (0x0C ) # V
46
51
PM2_5_UINT16_X1 = const (0x0D ) # ug/m^3
47
52
PM10_UINT16_X1 = const (0x0E ) # ug/m^3
53
+ GENERIC_BOOLEAN = const (0x0F ) # 0 (False = Off) 1 (True = On)
48
54
CO2_UINT16_X1 = const (0x12 ) # ppm
49
55
TVOC_UINT16_X1 = const (0x13 ) # ug/m^3
50
56
MOISTURE_UINT16_X100 = const (0x14 ) # %
57
+ BATTERY_LOW_BINARY = const (0x15 ) # 0 (False = Normal) 1 (True = Low)
58
+ BATTERY_CHARGING_BINARY = const (0x16 ) # 0 (False = Not Charging) 1 (True = Charging)
59
+ CARBON_MONOXIDE_BINARY = const (0x17 ) # 0 (False = Not detected) 1 (True = Detected)
60
+ COLD_BINARY = const (0x18 ) # 0 (False = Normal) 1 (True = Cold)
61
+ CONNECTIVITY_BINARY = const (0x19 ) # 0 (False = Disconnected) 1 (True = Connected)
62
+ DOOR_BINARY = const (0x1A ) # 0 (False = Closed) 1 (True = Open)
63
+ GARAGE_DOOR_BINARY = const (0x1B ) # 0 (False = Closed) 1 (True = Open)
64
+ GAS_BINARY = const (0x1C ) # 0 (False = Clear) 1 (True = Detected)
65
+ HEAT_BINARY = const (0x1D ) # 0 (False = Normal) 1 (True = Hot)
51
66
HUMIDITY_UINT8_X1 = const (0x2E ) # %
52
67
MOISTURE_UINT8_X1 = const (0x2F ) # %
53
68
COUNT_UINT16_X1 = const (0x3D )
@@ -77,7 +92,7 @@ class BTHome:
77
92
VOLUME_STORAGE_UINT32_X1000 = const (0x55 ) # L
78
93
CONDUCTIVITY_UINT16_X1 = const (0x56 ) # µS/cm
79
94
TEMPERATURE_SINT8_X1 = const (0x57 ) # °C
80
- # Skipping 0x58 due to strange factor of 0.35
95
+ # Skipping temperature 0x58 due to strange factor of 0.35
81
96
COUNT_SINT8_X1 = const (0x59 )
82
97
COUNT_SINT16_X1 = const (0x5A )
83
98
COUNT_SINT32_X1 = const (0x5B )
@@ -90,75 +105,102 @@ class BTHome:
90
105
# There is more than one way to represent most sensor properties. This
91
106
# dictionary maps the object id to the property name.
92
107
_object_id_properties = {
93
- BATTERY_UINT8_X1 : "battery" ,
94
- TEMPERATURE_SINT16_X100 : "temperature" ,
95
- HUMIDITY_UINT16_X100 : "humidity" ,
96
- PRESSURE_UINT24_X100 : "pressure" ,
97
- ILLUMINANCE_UINT24_X100 : "illuminance" ,
98
- MASS_KG_UINT16_X100 : "mass" ,
99
- MASS_LB_UINT16_X100 : "mass" ,
100
- DEWPOINT_SINT16_X100 : "dewpoint" ,
101
- COUNT_UINT8_X1 : "count" ,
102
- ENERGY_UINT24_X1000 : "energy" ,
103
- POWER_UINT24_X100 : "power" ,
104
- VOLTAGE_UINT16_X1000 : "voltage" ,
105
- PM2_5_UINT16_X1 : "pm2.5" ,
106
- PM10_UINT16_X1 : "pm10" ,
107
- CO2_UINT16_X1 : "co2" ,
108
- TVOC_UINT16_X1 : "tvoc" ,
109
- MOISTURE_UINT16_X100 : "moisture" ,
110
- HUMIDITY_UINT8_X1 : "humidity" ,
111
- MOISTURE_UINT8_X1 : "moisture" ,
112
- COUNT_UINT16_X1 : "count" ,
113
- COUNT_UINT32_X1 : "count" ,
114
- ROTATION_SINT16_X10 : "rotation" ,
115
- DISTANCE_MM_UINT16_X1 : "distance" ,
116
- DISTANCE_M_UINT16_X10 : "distance" ,
117
- DURATION_UINT24_X1000 : "duration" ,
118
- CURRENT_UINT16_X1000 : "current" ,
119
- TEMPERATURE_SINT16_X10 : "temperature" ,
120
- UV_INDEX_UINT8_X10 : "uv_index" ,
121
- VOLUME_L_UINT16_X10 : "volume" ,
122
- VOLUME_ML_UINT16_X1 : "volume" ,
123
- VOLUME_FLOW_RATE_X1000 : "volume_flow_rate" ,
124
- VOLTAGE_UINT16_X10 : "voltage" ,
125
- GAS_UINT24_X1000 : "gas" ,
126
- GAS_UINT32_X1000 : "gas" ,
127
- ENERGY_UINT32_X1000 : "energy" ,
128
- VOLUME_UINT32_X1000 : "volume" ,
129
- WATER_UINT32_X1000 : "water" ,
130
- TIMESTAMP_UINT48_X1 : "timestamp" ,
131
- ACCELERATION_UINT16_X1000 : "acceleration" ,
132
- GYROSCOPE_UINT16_X1000 : "gyroscope" ,
133
- VOLUME_STORAGE_UINT32_X1000 : "volume_storage" ,
134
- CONDUCTIVITY_UINT16_X1 : "conductivity" ,
135
- TEMPERATURE_SINT8_X1 : "temperature" ,
136
- COUNT_SINT8_X1 : "count" ,
137
- COUNT_SINT16_X1 : "count" ,
138
- COUNT_SINT32_X1 : "count" ,
139
- POWER_SINT16_X100 : "power" ,
140
- CURRENT_SINT16_X1000 : "current" ,
141
- DIRECTION_UINT16_X100 : "direction" ,
142
- PRECIPITATION_UINT16_X1 : "precipitation" ,
143
- CHANNEL_UINT8_X1 : "channel"
108
+ BATTERY_UINT8_X1 : "battery" , # 0x01
109
+ TEMPERATURE_SINT16_X100 : "temperature" , # 0x02
110
+ HUMIDITY_UINT16_X100 : "humidity" , # 0x03
111
+ PRESSURE_UINT24_X100 : "pressure" , # 0x04
112
+ ILLUMINANCE_UINT24_X100 : "illuminance" , # 0x05
113
+ MASS_KG_UINT16_X100 : "mass" , # 0x06
114
+ MASS_LB_UINT16_X100 : "mass" , # 0x07
115
+ DEWPOINT_SINT16_X100 : "dewpoint" , # 0x08
116
+ COUNT_UINT8_X1 : "count" , # 0x09
117
+ ENERGY_UINT24_X1000 : "energy" , # 0x0A
118
+ POWER_UINT24_X100 : "power" , # 0x0B
119
+ VOLTAGE_UINT16_X1000 : "voltage" , # 0x0C
120
+ PM2_5_UINT16_X1 : "pm2.5" , # 0x0D
121
+ PM10_UINT16_X1 : "pm10" , # 0x0E
122
+ GENERIC_BOOLEAN : "generic_boolean" , # 0x0F
123
+ CO2_UINT16_X1 : "co2" , # 0x12
124
+ TVOC_UINT16_X1 : "tvoc" , # 0x13
125
+ MOISTURE_UINT16_X100 : "moisture" , # 0x14
126
+ BATTERY_LOW_BINARY : "battery_low" , # 0x15
127
+ BATTERY_CHARGING_BINARY : "battery_charging" , # 0x16
128
+ CARBON_MONOXIDE_BINARY : "carbon_monoxide" , # 0x17
129
+ COLD_BINARY : "cold" , # 0x18
130
+ CONNECTIVITY_BINARY : "connectivity" , # 0x19
131
+ DOOR_BINARY : "door" , # 0x1A
132
+ GARAGE_DOOR_BINARY : "garage_door" , # 0x1B
133
+ GAS_BINARY : "gas_detected" , # 0x1C
134
+ HEAT_BINARY : "heat" , # 0x1D
135
+ HUMIDITY_UINT8_X1 : "humidity" , # 0x2E
136
+ MOISTURE_UINT8_X1 : "moisture" , # 0x2F
137
+ COUNT_UINT16_X1 : "count" , # 0x3D
138
+ COUNT_UINT32_X1 : "count" , # 0x3E
139
+ ROTATION_SINT16_X10 : "rotation" , # 0x3F
140
+ DISTANCE_MM_UINT16_X1 : "distance" , # 0x40
141
+ DISTANCE_M_UINT16_X10 : "distance" , # 0x41
142
+ DURATION_UINT24_X1000 : "duration" , # 0x42
143
+ CURRENT_UINT16_X1000 : "current" , # 0x43
144
+ SPEED_UINT16_X100 : "speed" , # 0x44
145
+ TEMPERATURE_SINT16_X10 : "temperature" , # 0x45
146
+ UV_INDEX_UINT8_X10 : "uv_index" , # 0x46
147
+ VOLUME_L_UINT16_X10 : "volume" , # 0x47
148
+ VOLUME_ML_UINT16_X1 : "volume" , # 0x48
149
+ VOLUME_FLOW_RATE_X1000 : "volume_flow_rate" , # 0x49
150
+ VOLTAGE_UINT16_X10 : "voltage" , # 0x4A
151
+ GAS_UINT24_X1000 : "gas" , # 0x4B
152
+ GAS_UINT32_X1000 : "gas" , # 0x4C
153
+ ENERGY_UINT32_X1000 : "energy" , # 0x4D
154
+ VOLUME_UINT32_X1000 : "volume" , # 0x4E
155
+ WATER_UINT32_X1000 : "water" , # 0x4F
156
+ TIMESTAMP_UINT48_X1 : "timestamp" , # 0x50
157
+ ACCELERATION_UINT16_X1000 : "acceleration" , # 0x51
158
+ GYROSCOPE_UINT16_X1000 : "gyroscope" , # 0x52
159
+ TEXT_BYTES : "text" , # 0x53
160
+ RAW_BYTES : "raw" , # 0x54
161
+ VOLUME_STORAGE_UINT32_X1000 : "volume_storage" , # 0x55
162
+ CONDUCTIVITY_UINT16_X1 : "conductivity" , # 0x56
163
+ TEMPERATURE_SINT8_X1 : "temperature" , # 0x57
164
+ # Skipping 0x58 temperature due to strange factor of 0.35
165
+ COUNT_SINT8_X1 : "count" , # 0x59
166
+ COUNT_SINT16_X1 : "count" , # 0x5A
167
+ COUNT_SINT32_X1 : "count" , # 0x5B
168
+ POWER_SINT16_X100 : "power" , # 0x5C
169
+ CURRENT_SINT16_X1000 : "current" , # 0x5D
170
+ DIRECTION_UINT16_X100 : "direction" , # 0x5E
171
+ PRECIPITATION_UINT16_X1 : "precipitation" , # 0x5F
172
+ CHANNEL_UINT8_X1 : "channel" # 0x60
144
173
}
145
174
146
175
# Properties below are updated externally when sensor values are read.
176
+ # There is some overlap in property names in the BTHome format. For
177
+ # example: moisture as in percent and moisture as in detected.
178
+ # In these cases, the binary property will have "_detected" appended.
147
179
# See "Sensor Data" table at https://bthome.io/format/ Property column.
148
180
acceleration = 0
149
181
battery = 0
182
+ battery_low = False
183
+ battery_charging = False
184
+ carbon_monoxide = False
150
185
channel = 0
151
186
co2 = 0
187
+ cold = False
152
188
conductivity = 0
189
+ connectivity = False
153
190
count = 0
154
191
current = 0
155
192
dewpoint = 0
156
193
direction = 0
157
194
distance = 0
195
+ door = False
158
196
duration = 0
159
197
energy = 0
198
+ garage_door = False
160
199
gas = 0
200
+ gas_detected = False
201
+ generic_boolean = False
161
202
gyroscope = 0
203
+ heat = False
162
204
humidity = 0
163
205
illuminance = 0
164
206
mass = 0
@@ -196,6 +238,10 @@ def local_name(self):
196
238
# is based on 3.4. Also, __func__ and __get()__ workarounds throw errors in
197
239
# MicroPython. [^4]
198
240
241
+ # Binary flag (true/false, on/off)
242
+ def _pack_binary (self , object_id , value ):
243
+ return pack ("BB" , object_id , 1 if (value is True ) else 0 )
244
+
199
245
# 8-bit integer with scaling of 1 (no decimal places)
200
246
def _pack_int8_x1 (self , object_id , value ):
201
247
return pack ("BB" , object_id , round (value ))
@@ -246,23 +292,33 @@ def _pack_raw_text(self, object_id, value):
246
292
return packed_value
247
293
248
294
_object_id_functions = {
249
- BATTERY_UINT8_X1 : _pack_int8_x1 ,
250
- TEMPERATURE_SINT16_X100 : _pack_int16_x100 ,
251
- HUMIDITY_UINT16_X100 : _pack_int16_x100 ,
252
- PRESSURE_UINT24_X100 : _pack_int24_x100 ,
253
- ILLUMINANCE_UINT24_X100 : _pack_int24_x100 ,
254
- MASS_KG_UINT16_X100 : _pack_int16_x100 ,
255
- MASS_LB_UINT16_X100 : _pack_int16_x100 ,
256
- DEWPOINT_SINT16_X100 : _pack_int16_x100 ,
257
- COUNT_UINT8_X1 : _pack_int8_x1 ,
258
- ENERGY_UINT24_X1000 : _pack_int24_x1000 ,
259
- POWER_UINT24_X100 : _pack_int24_x100 ,
260
- VOLTAGE_UINT16_X1000 : _pack_int16_x1000 ,
261
- PM2_5_UINT16_X1 : _pack_int16_x1 ,
262
- PM10_UINT16_X1 : _pack_int16_x1 ,
263
- CO2_UINT16_X1 : _pack_int16_x1 ,
295
+ BATTERY_UINT8_X1 : _pack_int8_x1 , # 0x01
296
+ TEMPERATURE_SINT16_X100 : _pack_int16_x100 , # 0x02
297
+ HUMIDITY_UINT16_X100 : _pack_int16_x100 , # 0x03
298
+ PRESSURE_UINT24_X100 : _pack_int24_x100 , # 0x04
299
+ ILLUMINANCE_UINT24_X100 : _pack_int24_x100 , # 0x05
300
+ MASS_KG_UINT16_X100 : _pack_int16_x100 , # 0x06
301
+ MASS_LB_UINT16_X100 : _pack_int16_x100 , # 0x07
302
+ DEWPOINT_SINT16_X100 : _pack_int16_x100 , # 0x08
303
+ COUNT_UINT8_X1 : _pack_int8_x1 , # 0x09
304
+ ENERGY_UINT24_X1000 : _pack_int24_x1000 , # 0x0A
305
+ POWER_UINT24_X100 : _pack_int24_x100 , # 0x0B
306
+ VOLTAGE_UINT16_X1000 : _pack_int16_x1000 , # 0x0C
307
+ PM2_5_UINT16_X1 : _pack_int16_x1 , # 0x0D
308
+ PM10_UINT16_X1 : _pack_int16_x1 , # 0x0E
309
+ GENERIC_BOOLEAN : _pack_binary , # 0x0F
310
+ CO2_UINT16_X1 : _pack_int16_x1 , # 0x12
264
311
TVOC_UINT16_X1 : _pack_int16_x1 ,
265
312
MOISTURE_UINT16_X100 : _pack_int16_x100 ,
313
+ BATTERY_LOW_BINARY : _pack_binary ,
314
+ BATTERY_CHARGING_BINARY : _pack_binary ,
315
+ CARBON_MONOXIDE_BINARY : _pack_binary ,
316
+ COLD_BINARY : _pack_binary ,
317
+ CONNECTIVITY_BINARY : _pack_binary ,
318
+ DOOR_BINARY : _pack_binary ,
319
+ GARAGE_DOOR_BINARY : _pack_binary ,
320
+ GAS_BINARY : _pack_binary ,
321
+ HEAT_BINARY : _pack_binary ,
266
322
HUMIDITY_UINT8_X1 : _pack_int8_x1 ,
267
323
MOISTURE_UINT8_X1 : _pack_int8_x1 ,
268
324
COUNT_UINT16_X1 : _pack_int16_x1 ,
0 commit comments