Announce a doorbell with proactivelyReported and a scene with supportsDeactivation

An interface without properties says beside its name what Alexa has to know
of it; the library left both out. With a board and Alexa on 2026-09-28 the
discovery of a doorbell was accepted (202), the endpoint was not listed, and
its DoorbellPress was answered with 500 INTERNAL_SERVICE_EXCEPTION.

DoorbellEventSource now always carries "proactivelyReported": true.
SceneController carries "supportsDeactivation", false until the sketch calls
setSupportsDeactivation(true); on another interface the call is refused and
logged. The Scene example says that it can be undone.

148 host tests. Light: static RAM 30,616 B, flash 332,705 B (+140 B).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
David 2026-09-28 22:20:34 +00:00
parent 1b8a5ff806
commit c3d02f462e
11 changed files with 65 additions and 18 deletions

View file

@ -247,7 +247,7 @@ void test_scene_is_announced_without_properties(void)
device.addCapability(AlexaInterfaces::SceneController);
assertDiscovery(endpoint("Movie Night", "SCENE_TRIGGER",
"{\"interface\":\"Alexa.SceneController\",\"version\":\"3\",\"type\":\"AlexaInterface\"}"),
"{\"interface\":\"Alexa.SceneController\",\"version\":\"3\",\"type\":\"AlexaInterface\",\"supportsDeactivation\":false}"),
device);
}
@ -421,14 +421,32 @@ void test_toggle_controller_that_only_reports_is_announced_as_non_controllable(v
device);
}
// alexa-scenecontroller.html: supportsDeactivation says whether Alexa may send Deactivate
void test_scene_that_can_be_undone_says_so_and_no_other_interface_can(void)
{
AlexaDevice device("Movie Night", "root", "ESP-01");
device.setDisplayCategory(DisplayCategory::SCENE_TRIGGER);
device.addCapability(AlexaInterfaces::SceneController)->setSupportsDeactivation(true);
assertDiscovery(endpoint("Movie Night", "SCENE_TRIGGER",
"{\"interface\":\"Alexa.SceneController\",\"version\":\"3\",\"type\":\"AlexaInterface\",\"supportsDeactivation\":true}"),
device);
AlexaDevice lamp("Lamp", "root", "ESP-02");
AlexaCapability *power = lamp.addCapability(AlexaInterfaces::PowerController);
TEST_ASSERT_TRUE(power->isValid());
power->setSupportsDeactivation(true);
TEST_ASSERT_FALSE_MESSAGE(power->isValid(), "a call the interface cannot take is a refused call");
}
void test_doorbell_is_announced_without_properties(void)
{
AlexaDevice device("Front Door", "root", "ESP-01");
device.setDisplayCategory(DisplayCategory::DOORBELL);
device.addCapability(AlexaInterfaces::DoorbellEventSource)->setProactivelyReported(true);
device.addCapability(AlexaInterfaces::DoorbellEventSource);
assertDiscovery(endpoint("Front Door", "DOORBELL",
"{\"interface\":\"Alexa.DoorbellEventSource\",\"version\":\"3\",\"type\":\"AlexaInterface\"}"),
"{\"interface\":\"Alexa.DoorbellEventSource\",\"version\":\"3\",\"type\":\"AlexaInterface\",\"proactivelyReported\":true}"),
device);
}
@ -769,6 +787,7 @@ int main(int, char **)
RUN_TEST(test_range_controller_blind_is_announced_with_names_configuration_and_semantics);
RUN_TEST(test_mode_controller_is_announced_with_its_modes_and_text_states);
RUN_TEST(test_toggle_controller_that_only_reports_is_announced_as_non_controllable);
RUN_TEST(test_scene_that_can_be_undone_says_so_and_no_other_interface_can);
RUN_TEST(test_doorbell_is_announced_without_properties);
RUN_TEST(test_playback_and_wake_on_lan_are_announced_with_empty_properties);
RUN_TEST(test_instance_and_friendly_name_are_copied);