diff --git a/README.md b/README.md index 27e612b..a412190 100644 --- a/README.md +++ b/README.md @@ -50,6 +50,30 @@ docker run \ Bonob will now auto-register itself with sonos on startup, updating the registration if the configuration has changed. Bonob should show up in the "Services" list on http://localhost:3000 + +### Running bonob on a different network to your sonos devices. +Start bonob without sonos discovery or registration, ie. +``` +docker run \ + -e BONOB_PORT=4534 \ + -e BONOB_WEB_ADDRESS=http://my-bonob-service:4534 \ + -e BONOB_SONOS_AUTO_REGISTER=false \ + -e BONOB_SONOS_DEVICE_DISCOVERY=false \ + -p 4534 \ + simojenki/bonob +``` + +Run bonob registration within the network that contains your sonos devices, using the same BONOB_WEB_ADDRESS and discovery and registration enabled +``` +docker run \ + -e BONOB_PORT=4534 \ + -e BONOB_WEB_ADDRESS=http://my-bonob-service:4534 \ + -e BONOB_SONOS_AUTO_REGISTER=true \ + -e BONOB_SONOS_DEVICE_DISCOVERY=true \ + simojenki/bonob registrar +``` + + ## Configuration item | default value | description diff --git a/src/app.ts b/src/app.ts index 07c01b4..011da3f 100644 --- a/src/app.ts +++ b/src/app.ts @@ -1,35 +1,41 @@ -import { hostname } from "os"; -import sonos, { bonobService } from "./sonos"; import server from "./server"; import logger from "./logger"; -import { DEFAULT, Navidrome, appendMimeTypeToClientFor } from "./navidrome"; +import { appendMimeTypeToClientFor, DEFAULT, Navidrome } from "./navidrome"; import encryption from "./encryption"; import { InMemoryAccessTokens, sha256 } from "./access_tokens"; import { InMemoryLinkCodes } from "./link_codes"; +import config from "./config"; +import sonos, { bonobService } from "./sonos"; -const PORT = +(process.env["BONOB_PORT"] || 4534); -const WEB_ADDRESS = - process.env["BONOB_WEB_ADDRESS"] || `http://${hostname()}:${PORT}`; - -if (WEB_ADDRESS.match("localhost")) { - logger.error("BONOB_WEB_ADDRESS containing localhost is almost certainly incorrect, sonos devices will not be able to communicate with bonob using localhost, please specify either public IP or DNS entry"); - process.exit(1); -} - -const SONOS_DEVICE_DISCOVERY = - (process.env["BONOB_SONOS_DEVICE_DISCOVERY"] || "true") == "true"; -const SONOS_SEED_HOST = process.env["BONOB_SONOS_SEED_HOST"]; +logger.info( + `Starting bonob with config ${JSON.stringify(config)}` +); const bonob = bonobService( - process.env["BONOB_SONOS_SERVICE_NAME"] || "bonob", - Number(process.env["BONOS_SONOS_SERVICE_ID"] || "246"), - WEB_ADDRESS, + config.sonos.serviceName, + config.sonos.sid, + config.webAddress, "AppLink" ); -const secret = process.env["BONOB_SECRET"] || "bonob"; -const sonosSystem = sonos(SONOS_DEVICE_DISCOVERY, SONOS_SEED_HOST); -if (process.env["BONOB_SONOS_AUTO_REGISTER"] == "true") { +const sonosSystem = sonos(config.sonos.deviceDiscovery, config.sonos.seedHost); + +const streamUserAgent = config.navidrome.customClientsFor ? appendMimeTypeToClientFor(config.navidrome.customClientsFor.split(",")) : DEFAULT; + +const app = server( + sonosSystem, + bonob, + config.webAddress, + new Navidrome( + config.navidrome.url, + encryption(config.secret), + streamUserAgent + ), + new InMemoryLinkCodes(), + new InMemoryAccessTokens(sha256(config.secret)) +); + +if (config.sonos.autoRegister) { sonosSystem.register(bonob).then((success) => { if (success) { logger.info( @@ -39,25 +45,8 @@ if (process.env["BONOB_SONOS_AUTO_REGISTER"] == "true") { }); } -const customClientsFor = process.env["BONOB_NAVIDROME_CUSTOM_CLIENTS"] || "none"; -const streamUserAgent = -customClientsFor == "none" ? DEFAULT : appendMimeTypeToClientFor(customClientsFor.split(",")); - -const app = server( - sonosSystem, - bonob, - WEB_ADDRESS, - new Navidrome( - process.env["BONOB_NAVIDROME_URL"] || `http://${hostname()}:4533`, - encryption(secret), - streamUserAgent - ), - new InMemoryLinkCodes(), - new InMemoryAccessTokens(sha256(secret)) -); - -app.listen(PORT, () => { - logger.info(`Listening on ${PORT} available @ ${WEB_ADDRESS}`); +app.listen(config.port, () => { + logger.info(`Listening on ${config.port} available @ ${config.webAddress}`); }); export default app; diff --git a/src/config.ts b/src/config.ts new file mode 100644 index 0000000..bbe57ea --- /dev/null +++ b/src/config.ts @@ -0,0 +1,30 @@ +import { hostname } from "os"; +import logger from "./logger"; + +const port = +(process.env["BONOB_PORT"] || 4534); +const webAddress = + process.env["BONOB_WEB_ADDRESS"] || `http://${hostname()}:${port}`; + +if (webAddress.match("localhost")) { + logger.error("BONOB_WEB_ADDRESS containing localhost is almost certainly incorrect, sonos devices will not be able to communicate with bonob using localhost, please specify either public IP or DNS entry"); + process.exit(1); +} + +export default { + port, + webAddress, + secret: process.env["BONOB_SECRET"] || "bonob", + sonos: { + serviceName: process.env["BONOB_SONOS_SERVICE_NAME"] || "bonob", + deviceDiscovery: (process.env["BONOB_SONOS_DEVICE_DISCOVERY"] || "true") == "true", + seedHost: process.env["BONOB_SONOS_SEED_HOST"], + autoRegister: process.env["BONOB_SONOS_AUTO_REGISTER"] == "true", + sid: Number(process.env["BONOS_SONOS_SERVICE_ID"] || "246") + }, + navidrome: { + url: process.env["BONOB_NAVIDROME_URL"] || `http://${hostname()}:4533`, + customClientsFor: process.env["BONOB_NAVIDROME_CUSTOM_CLIENTS"] || undefined, + } +} + + diff --git a/src/register.ts b/src/register.ts new file mode 100644 index 0000000..e77e995 --- /dev/null +++ b/src/register.ts @@ -0,0 +1,20 @@ +import config from "./config"; +import logger from "./logger"; +import sonos, { bonobService } from "./sonos"; + +const bonob = bonobService( + config.sonos.serviceName, + config.sonos.sid, + config.webAddress, + "AppLink" +); + +const sonosSystem = sonos(config.sonos.deviceDiscovery, config.sonos.seedHost); + +sonosSystem.register(bonob).then((success) => { + if (success) { + logger.info( + `Successfully registered ${bonob.name}(SID:${bonob.sid}) with sonos` + ); + } +}); \ No newline at end of file