bridge: subscribe to discover and +/alexaDirective only
The bridge subscribed to <root>/#, so the broker sent back every discover_r, alexaResponce and changeReport
the bridge published, and the backend's <endpointId>/alexaDirective_e. It now subscribes to <root>/discover
and <root>/+/alexaDirective, both named in src/topics.ts; a directive topic is recognised by the root and the
last segment instead of by counting three segments.
The test reads the subscriptions from the broker, publishes seven other topics under the root and one
directive for each of two endpoints: the bridge receives the two directives and the discovery request,
nothing else. Tests: 148 -> 150 (the count in the body of 6789a1a, 108 -> 113, should read 143 -> 148).
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
parent
6789a1a077
commit
e0fe9d2812
11 changed files with 225 additions and 93 deletions
61
dist/esm/Alex2Node.js
vendored
61
dist/esm/Alex2Node.js
vendored
|
|
@ -18,7 +18,7 @@ const DESCRIBED = [
|
|||
* directive dispatch.
|
||||
*
|
||||
* Events (all optional to listen to - since 1.5.1 a broker outage never throws out of the library):
|
||||
* "connect" connected (or reconnected) and subscribed to <root>/#
|
||||
* "connect" connected (or reconnected) and subscribed to <root>/discover and <root>/+/alexaDirective
|
||||
* "offline" the connection dropped; mqtt.js reconnects on its own (reconnectPeriod, default 1 s)
|
||||
* "reconnect" a reconnect attempt starts
|
||||
* "close" the connection closed
|
||||
|
|
@ -77,7 +77,7 @@ class Alex2MQTT extends EventEmitter {
|
|||
this.client.on("connect", () => {
|
||||
this.connected = true;
|
||||
this.log("Connected to MQTT broker");
|
||||
this.client.subscribe(this.rootTopic + "/#", (err) => {
|
||||
this.client.subscribe(topics.subscriptions(this.rootTopic), (err) => {
|
||||
if (err) {
|
||||
this.fail(err);
|
||||
return;
|
||||
|
|
@ -92,7 +92,7 @@ class Alex2MQTT extends EventEmitter {
|
|||
this.client.on("error", (err) => { this.connected = false; this.fail(err); });
|
||||
this.client.on("message", (topic, message) => {
|
||||
this.log(`MQTT Message Received`, { topic, payload: message.toString() });
|
||||
if (topic == `${this.rootTopic}/discover`) {
|
||||
if (topic === topics.discover(this.rootTopic)) {
|
||||
this.log("Discovery request received, getting device json...");
|
||||
const deviceArray = this.describeDevices();
|
||||
this.lastDiscoveryAt = new Date().toISOString();
|
||||
|
|
@ -104,35 +104,34 @@ class Alex2MQTT extends EventEmitter {
|
|||
this.log(`Discovery payloads published to ${result.topic}`, deviceArray);
|
||||
this.emit("discover", deviceArray.length);
|
||||
});
|
||||
return;
|
||||
}
|
||||
else if (topic.split("/").length == 3) {
|
||||
const [, endpointId, directiveType] = topic.split("/");
|
||||
if (directiveType != "alexaDirective") {
|
||||
return;
|
||||
}
|
||||
const device = this.devices.find((d) => d.endpointId === endpointId);
|
||||
if (!device) {
|
||||
this.log(`No device found for endpointId: ${endpointId}`);
|
||||
return;
|
||||
}
|
||||
let payload;
|
||||
try {
|
||||
payload = JSON.parse(message.toString());
|
||||
}
|
||||
catch (e) {
|
||||
this.log(`Failed to parse payload JSON`, e);
|
||||
return;
|
||||
}
|
||||
if (!payload || !payload.header)
|
||||
return;
|
||||
this.emit("directive", { endpointId, namespace: payload.header.namespace, name: payload.header.name });
|
||||
if (payload.header.namespace === "Alexa" && payload.header.name === "ReportState") {
|
||||
this.log(`ReportState directive for device ${endpointId}`);
|
||||
device.emit("ReportState", payload);
|
||||
}
|
||||
else {
|
||||
device.emit("Event", payload, payload.header.namespace);
|
||||
}
|
||||
// Another topic can still arrive: a broker may deliver what an earlier session of this client id subscribed to
|
||||
const endpointId = topics.directiveEndpoint(this.rootTopic, topic);
|
||||
if (endpointId === null)
|
||||
return;
|
||||
const device = this.devices.find((d) => d.endpointId === endpointId);
|
||||
if (!device) {
|
||||
this.log(`No device found for endpointId: ${endpointId}`);
|
||||
return;
|
||||
}
|
||||
let payload;
|
||||
try {
|
||||
payload = JSON.parse(message.toString());
|
||||
}
|
||||
catch (e) {
|
||||
this.log(`Failed to parse payload JSON`, e);
|
||||
return;
|
||||
}
|
||||
if (!payload || !payload.header)
|
||||
return;
|
||||
this.emit("directive", { endpointId, namespace: payload.header.namespace, name: payload.header.name });
|
||||
if (payload.header.namespace === "Alexa" && payload.header.name === "ReportState") {
|
||||
this.log(`ReportState directive for device ${endpointId}`);
|
||||
device.emit("ReportState", payload);
|
||||
}
|
||||
else {
|
||||
device.emit("Event", payload, payload.header.namespace);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue