mirror of
https://github.com/esphome/esphome.git
synced 2025-10-29 22:24:26 +00:00
Add support for BLE passkey authentication (#4258)
Co-authored-by: Branden Cash <203336+ammmze@users.noreply.github.com>
This commit is contained in:
@@ -29,8 +29,35 @@ BLEClientConnectTrigger = ble_client_ns.class_(
|
||||
BLEClientDisconnectTrigger = ble_client_ns.class_(
|
||||
"BLEClientDisconnectTrigger", automation.Trigger.template(BLEClientNodeConstRef)
|
||||
)
|
||||
BLEClientPasskeyRequestTrigger = ble_client_ns.class_(
|
||||
"BLEClientPasskeyRequestTrigger", automation.Trigger.template(BLEClientNodeConstRef)
|
||||
)
|
||||
BLEClientPasskeyNotificationTrigger = ble_client_ns.class_(
|
||||
"BLEClientPasskeyNotificationTrigger",
|
||||
automation.Trigger.template(BLEClientNodeConstRef, cg.uint32),
|
||||
)
|
||||
BLEClientNumericComparisonRequestTrigger = ble_client_ns.class_(
|
||||
"BLEClientNumericComparisonRequestTrigger",
|
||||
automation.Trigger.template(BLEClientNodeConstRef, cg.uint32),
|
||||
)
|
||||
|
||||
# Actions
|
||||
BLEWriteAction = ble_client_ns.class_("BLEClientWriteAction", automation.Action)
|
||||
BLEPasskeyReplyAction = ble_client_ns.class_(
|
||||
"BLEClientPasskeyReplyAction", automation.Action
|
||||
)
|
||||
BLENumericComparisonReplyAction = ble_client_ns.class_(
|
||||
"BLEClientNumericComparisonReplyAction", automation.Action
|
||||
)
|
||||
BLERemoveBondAction = ble_client_ns.class_(
|
||||
"BLEClientRemoveBondAction", automation.Action
|
||||
)
|
||||
|
||||
CONF_PASSKEY = "passkey"
|
||||
CONF_ACCEPT = "accept"
|
||||
CONF_ON_PASSKEY_REQUEST = "on_passkey_request"
|
||||
CONF_ON_PASSKEY_NOTIFICATION = "on_passkey_notification"
|
||||
CONF_ON_NUMERIC_COMPARISON_REQUEST = "on_numeric_comparison_request"
|
||||
|
||||
# Espressif platformio framework is built with MAX_BLE_CONN to 3, so
|
||||
# enforce this in yaml checks.
|
||||
@@ -56,6 +83,29 @@ CONFIG_SCHEMA = (
|
||||
),
|
||||
}
|
||||
),
|
||||
cv.Optional(CONF_ON_PASSKEY_REQUEST): automation.validate_automation(
|
||||
{
|
||||
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(
|
||||
BLEClientPasskeyRequestTrigger
|
||||
),
|
||||
}
|
||||
),
|
||||
cv.Optional(CONF_ON_PASSKEY_NOTIFICATION): automation.validate_automation(
|
||||
{
|
||||
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(
|
||||
BLEClientPasskeyNotificationTrigger
|
||||
),
|
||||
}
|
||||
),
|
||||
cv.Optional(
|
||||
CONF_ON_NUMERIC_COMPARISON_REQUEST
|
||||
): automation.validate_automation(
|
||||
{
|
||||
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(
|
||||
BLEClientNumericComparisonRequestTrigger
|
||||
),
|
||||
}
|
||||
),
|
||||
}
|
||||
)
|
||||
.extend(cv.COMPONENT_SCHEMA)
|
||||
@@ -85,13 +135,34 @@ BLE_WRITE_ACTION_SCHEMA = cv.Schema(
|
||||
}
|
||||
)
|
||||
|
||||
BLE_NUMERIC_COMPARISON_REPLY_ACTION_SCHEMA = cv.Schema(
|
||||
{
|
||||
cv.GenerateID(CONF_ID): cv.use_id(BLEClient),
|
||||
cv.Required(CONF_ACCEPT): cv.templatable(cv.boolean),
|
||||
}
|
||||
)
|
||||
|
||||
BLE_PASSKEY_REPLY_ACTION_SCHEMA = cv.Schema(
|
||||
{
|
||||
cv.GenerateID(CONF_ID): cv.use_id(BLEClient),
|
||||
cv.Required(CONF_PASSKEY): cv.templatable(cv.int_range(min=0, max=999999)),
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
BLE_REMOVE_BOND_ACTION_SCHEMA = cv.Schema(
|
||||
{
|
||||
cv.GenerateID(CONF_ID): cv.use_id(BLEClient),
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@automation.register_action(
|
||||
"ble_client.ble_write", BLEWriteAction, BLE_WRITE_ACTION_SCHEMA
|
||||
)
|
||||
async def ble_write_to_code(config, action_id, template_arg, args):
|
||||
paren = await cg.get_variable(config[CONF_ID])
|
||||
var = cg.new_Pvariable(action_id, template_arg, paren)
|
||||
parent = await cg.get_variable(config[CONF_ID])
|
||||
var = cg.new_Pvariable(action_id, template_arg, parent)
|
||||
|
||||
value = config[CONF_VALUE]
|
||||
if cg.is_template(value):
|
||||
@@ -137,6 +208,54 @@ async def ble_write_to_code(config, action_id, template_arg, args):
|
||||
return var
|
||||
|
||||
|
||||
@automation.register_action(
|
||||
"ble_client.numeric_comparison_reply",
|
||||
BLENumericComparisonReplyAction,
|
||||
BLE_NUMERIC_COMPARISON_REPLY_ACTION_SCHEMA,
|
||||
)
|
||||
async def numeric_comparison_reply_to_code(config, action_id, template_arg, args):
|
||||
parent = await cg.get_variable(config[CONF_ID])
|
||||
var = cg.new_Pvariable(action_id, template_arg, parent)
|
||||
|
||||
accept = config[CONF_ACCEPT]
|
||||
if cg.is_template(accept):
|
||||
templ = await cg.templatable(accept, args, cg.bool_)
|
||||
cg.add(var.set_value_template(templ))
|
||||
else:
|
||||
cg.add(var.set_value_simple(accept))
|
||||
|
||||
return var
|
||||
|
||||
|
||||
@automation.register_action(
|
||||
"ble_client.passkey_reply", BLEPasskeyReplyAction, BLE_PASSKEY_REPLY_ACTION_SCHEMA
|
||||
)
|
||||
async def passkey_reply_to_code(config, action_id, template_arg, args):
|
||||
parent = await cg.get_variable(config[CONF_ID])
|
||||
var = cg.new_Pvariable(action_id, template_arg, parent)
|
||||
|
||||
passkey = config[CONF_PASSKEY]
|
||||
if cg.is_template(passkey):
|
||||
templ = await cg.templatable(passkey, args, cg.uint32)
|
||||
cg.add(var.set_value_template(templ))
|
||||
else:
|
||||
cg.add(var.set_value_simple(passkey))
|
||||
|
||||
return var
|
||||
|
||||
|
||||
@automation.register_action(
|
||||
"ble_client.remove_bond",
|
||||
BLERemoveBondAction,
|
||||
BLE_REMOVE_BOND_ACTION_SCHEMA,
|
||||
)
|
||||
async def remove_bond_to_code(config, action_id, template_arg, args):
|
||||
parent = await cg.get_variable(config[CONF_ID])
|
||||
var = cg.new_Pvariable(action_id, template_arg, parent)
|
||||
|
||||
return var
|
||||
|
||||
|
||||
async def to_code(config):
|
||||
var = cg.new_Pvariable(config[CONF_ID])
|
||||
await cg.register_component(var, config)
|
||||
@@ -148,3 +267,12 @@ async def to_code(config):
|
||||
for conf in config.get(CONF_ON_DISCONNECT, []):
|
||||
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var)
|
||||
await automation.build_automation(trigger, [], conf)
|
||||
for conf in config.get(CONF_ON_PASSKEY_REQUEST, []):
|
||||
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var)
|
||||
await automation.build_automation(trigger, [], conf)
|
||||
for conf in config.get(CONF_ON_PASSKEY_NOTIFICATION, []):
|
||||
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var)
|
||||
await automation.build_automation(trigger, [(cg.uint32, "passkey")], conf)
|
||||
for conf in config.get(CONF_ON_NUMERIC_COMPARISON_REQUEST, []):
|
||||
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var)
|
||||
await automation.build_automation(trigger, [(cg.uint32, "passkey")], conf)
|
||||
|
||||
Reference in New Issue
Block a user