Ability to auto-discover sonos devices or find by using a seed ip

This commit is contained in:
simojenki
2021-01-29 16:54:38 +11:00
parent 45fe62841f
commit 5cd98a5ea6
12 changed files with 2881 additions and 578 deletions

View File

@@ -1,26 +1,12 @@
import express from "express";
import * as Eta from "eta";
import sonos from "./sonos";
import server from "./server";
// import { Navidrome } from "./music_service";
import makeSonos from "./sonos";
const PORT = process.env["PORT"] || 3000;
const PORT = 3000;
const app = server(sonos(process.env["BONOB_SONOS_SEED_HOST"]));
makeSonos().then((sonos) => {
const app = express();
app.use(express.static("./web/public"));
app.engine("eta", Eta.renderFile);
app.set("view engine", "eta");
app.set("views", "./web/views");
app.get("/", (_, res) => {
res.render("index", {
devices: sonos.devices(),
});
});
app.listen(PORT, () => {
console.info(`Listening on ${PORT}`);
});
app.listen(PORT, () => {
console.info(`Listening on ${PORT}`);
});
export default app;

22
src/server.ts Normal file
View File

@@ -0,0 +1,22 @@
import express, { Express } from "express";
import * as Eta from "eta";
import { Sonos } from "./sonos";
function server(sonos: Sonos): Express {
const app = express();
app.use(express.static("./web/public"));
app.engine("eta", Eta.renderFile);
app.set("view engine", "eta");
app.set("views", "./web/views");
app.get("/", (_, res) => {
res.render("index", {
devices: sonos.devices(),
});
});
return app;
}
export default server;

View File

@@ -1,5 +1,4 @@
import { SonosManager } from "@svrooij/sonos";
import { SonosManager, SonosDevice } from "@svrooij/sonos";
import logger from "./logger";
type Device = {
@@ -9,40 +8,49 @@ type Device = {
port: number;
};
interface Sonos
{
export interface Sonos {
devices: () => Device[];
}
class RealSonos implements Sonos {
manager: SonosManager;
constructor(manager: SonosManager) {
this.manager = manager;
}
devices = (): Device[] => {
const devices = this.manager.Devices.map((d) => ({
name: d.Name,
group: d.GroupName || "",
ip: d.Host,
port: d.Port,
}));
logger.debug({ devices })
return devices;
}
}
const SonosDisabled: Sonos = {
export const SONOS_DISABLED: Sonos = {
devices: () => [],
};
export default function (): Promise<Sonos> {
const asDevice = (sonosDevice: SonosDevice) => ({
name: sonosDevice.Name,
group: sonosDevice.GroupName || "",
ip: sonosDevice.Host,
port: sonosDevice.Port,
});
const setupDiscovery = (manager: SonosManager, sonosSeedHost?: string): Promise<boolean> => {
if (sonosSeedHost == undefined || sonosSeedHost == "") {
logger.info("Trying to auto discover sonos devices");
return manager.InitializeWithDiscovery(10);
} else {
logger.info(`Trying to discover sonos devices using seed ${sonosSeedHost}`);
return manager.InitializeFromDevice(sonosSeedHost);
}
};
export function autoDiscoverySonos(sonosSeedHost?: string): Sonos {
const manager = new SonosManager();
return manager
.InitializeWithDiscovery(10)
.then((it) => (it ? new RealSonos(manager) : SonosDisabled))
.catch((_) => {
return SonosDisabled;
});
setupDiscovery(manager, sonosSeedHost).then((r) => {
if (r) logger.info({ devices: manager.Devices.map(asDevice) });
else logger.warn("Failed to auto discover hosts!");
});
return {
devices: () => manager.Devices.map(asDevice),
};
}
export default function sonos(sonosSeedHost?: string): Sonos {
switch (sonosSeedHost) {
case "disabled":
return SONOS_DISABLED;
default:
return autoDiscoverySonos(sonosSeedHost);
}
}