Audit of the paths that drop or refuse something. registerEvent() dropped an eleventh
handler and a second one for the same name without a word: the name now gets the new
handler, an eleventh name and a call without a name or a function print an error. A
device that cannot be announced printed two lines, one without its id; it prints one.
setLogLevel() above ALEX2ESP_LOG_MAX prints an error that names the build flag.
"the handler sent no answer" is an error for a handler of onDirective() only: a 1.x
handler may answer from a later loop(), its silence is a line at DEBUG.
getDevice() returning nullptr and printMemoryInfo() are documented; keywords.txt has
the 2.0 names and loses three that were removed.
basicLight: static RAM 30,520 B, flash 333,989 B (+600); ALEX2ESP_LOG_MAX=0 30,496 /
327,953, =3 30,520 / 334,477; five examples, log0 and log3 build with 0 warnings.
Host tests: 135 (dispatch 11 -> 16).
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
onDirective(handler) registers void handler(AlexaDirective&): the directive comes with its device, the
capability it is for, namespace, name, instance, correlationToken and payload, and response() and
stateReport() build the answer, so one function serves several devices. registerEvent() is kept; the
five examples compile unchanged and announce the same discovery objects.
Devices are a linked list on the bridge and a device holds ALEX2ESP_MAX_CAPABILITIES (8) capability
pointers in place of two std::deque; one capability more is refused with an error.
A device without a handler, and a handler that sends nothing for a capability the device lacks, are
answered with the ErrorResponse INVALID_DIRECTIVE instead of a timeout. A directive whose endpointId is
not a device of the sketch is ignored at DEBUG.
basicLight on a D1 mini: static RAM 30,672 -> 30,600 B, flash 332,541 -> 333,437 B, 0 warnings in the five
examples; 88 host tests (11 new, test/test_dispatch).
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>