zwave-js
Version:
Z-Wave driver written entirely in JavaScript/TypeScript
73 lines • 2.88 kB
JavaScript
import { Bytes, isUint8Array } from "@zwave-js/shared";
import { isArray, isObject } from "alcalzone-shared/typeguards";
const domain = "_zwave._tcp.local";
export async function discoverRemoteSerialPorts(timeout = 1000) {
const { default: createMDNSServer } = await import("mdns-server");
const mdns = createMDNSServer({
reuseAddr: true,
loopback: false,
noInit: true,
ttl: 10,
});
let timer;
return new Promise((resolve, reject) => {
mdns.on("response", (resp) => {
const matches = resp.answers
.filter((n) => n.type === "PTR"
&& n.name === domain
&& typeof n.data === "string")
.map(({ data }) => {
return {
txt: resp.answers.find((n) => n.type === "TXT" && n.name === data) ?? resp.additionals.find((n) => n.type === "TXT" && n.name === data),
srv: resp.answers.find((n) => n.type === "SRV" && n.name === data) ?? resp.additionals.find((n) => n.type === "SRV" && n.name === data),
};
})
.filter(({ srv }) => !!srv
&& isObject(srv.data)
&& typeof srv.data.target === "string"
&& typeof srv.data.port === "number")
.map(({ txt, srv }) => {
const info = {};
if (!!txt && isArray(txt.data)) {
const strings = txt.data
.filter((d) => isUint8Array(d))
.map((d) => Bytes.view(d).toString("utf8"))
.filter((d) => d.includes("="));
for (const string of strings) {
const [key, value] = string.split("=", 2);
info[key] = value;
}
}
const addr = srv.data;
const protocol = info.protocol?.toLowerCase() === "esphome"
? "esphome"
: "tcp";
const port = `${protocol}://${addr.target}:${addr.port}`;
return {
port,
info,
};
});
if (matches.length) {
clearTimeout(timer);
resolve(matches);
}
});
mdns.on("ready", () => {
mdns.query([
{ name: domain, type: "PTR" },
{ name: domain, type: "SRV" },
{ name: domain, type: "TXT" },
]);
});
mdns.on("error", reject);
mdns.initServer();
if (typeof timeout === "number" && timeout > 0) {
timer = setTimeout(() => {
mdns.destroy();
resolve(undefined);
}, timeout);
}
});
}
//# sourceMappingURL=node.js.map