Initial commit: esphome-xtool-ap2 ESPHome component
Control one or two xTool SafetyPro AP2 air purifiers over BLE and expose them to Home Assistant via an ESP32 (the ap2_hub external component): per-slot fan control with live gear sync, runtime-settable flash-persisted MACs, an on-device scanner, M9033 status polling (filter life, serial, firmware), buzzer control, and BLE bonding. Includes the PC debug tool (tools/ap2_ble.py) and the reverse-engineered protocol spec (SPEC.md). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,38 @@
|
||||
import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome.components import sensor
|
||||
from esphome.const import UNIT_PERCENT
|
||||
|
||||
from . import AP2Hub
|
||||
|
||||
CONF_AP2_HUB_ID = "ap2_hub_id"
|
||||
CONF_SLOT = "slot"
|
||||
CONF_TYPE = "type"
|
||||
|
||||
# Filter-life types -> index into AP2Filter (M9033 fields H I J K L S).
|
||||
FILTERS = {
|
||||
"pre_filter": 0,
|
||||
"medium_filter": 1,
|
||||
"activated_carbon": 2,
|
||||
"carbon_cloth": 3,
|
||||
"formaldehyde": 4,
|
||||
"hepa": 5,
|
||||
}
|
||||
|
||||
CONFIG_SCHEMA = sensor.sensor_schema(
|
||||
unit_of_measurement=UNIT_PERCENT,
|
||||
accuracy_decimals=0,
|
||||
icon="mdi:air-filter",
|
||||
).extend(
|
||||
{
|
||||
cv.GenerateID(CONF_AP2_HUB_ID): cv.use_id(AP2Hub),
|
||||
cv.Required(CONF_SLOT): cv.int_range(min=0, max=1),
|
||||
cv.Required(CONF_TYPE): cv.one_of(*FILTERS, lower=True),
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
async def to_code(config):
|
||||
var = await sensor.new_sensor(config)
|
||||
parent = await cg.get_variable(config[CONF_AP2_HUB_ID])
|
||||
cg.add(parent.set_filter_sensor(config[CONF_SLOT], FILTERS[config[CONF_TYPE]], var))
|
||||
Reference in New Issue
Block a user