mirror of
https://github.com/wkulhanek/bonob.git
synced 2025-12-21 17:33:29 +01:00
When running bonob outside of sonos network ability to register with sonos using remote bonob
This commit is contained in:
15
README.md
15
README.md
@@ -54,15 +54,17 @@ Bonob will now auto-register itself with sonos on startup, updating the registra
|
|||||||
|
|
||||||
### Running bonob on a different network to your sonos devices
|
### Running bonob on a different network to your sonos devices
|
||||||
|
|
||||||
Running bonob outside of your lan will require registering your bonob install with your sonos devices from within your lan.
|
Running bonob outside of your lan will require registering your bonob install with your sonos devices from within your LAN.
|
||||||
|
|
||||||
If you are running this on the internet, you should put bonob behind a reverse proxy and use certificates/https.
|
If you are using bonob over the Internet, you do this at your own risk and should use TLS.
|
||||||
|
|
||||||
Start bonob outside the lan with sonos discovery & registration disabled as they are meaningless in this case, ie.
|
Start bonob outside the LAN with sonos discovery & registration disabled as they are meaningless in this case, ie.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker run \
|
docker run \
|
||||||
-e BONOB_PORT=4534 \
|
-e BONOB_PORT=4534 \
|
||||||
|
-e BONOB_SONOS_SERVICE_NAME=MyAwesomeMusic \
|
||||||
|
-e BONOB_SECRET=changeme \
|
||||||
-e BONOB_URL=https://my-server.example.com/bonob \
|
-e BONOB_URL=https://my-server.example.com/bonob \
|
||||||
-e BONOB_SONOS_AUTO_REGISTER=false \
|
-e BONOB_SONOS_AUTO_REGISTER=false \
|
||||||
-e BONOB_SONOS_DEVICE_DISCOVERY=false \
|
-e BONOB_SONOS_DEVICE_DISCOVERY=false \
|
||||||
@@ -71,17 +73,16 @@ docker run \
|
|||||||
simojenki/bonob
|
simojenki/bonob
|
||||||
```
|
```
|
||||||
|
|
||||||
Now inside the lan that contains the sonos devices run bonob registration, using the same BONOB_URL as above, and with discovery enabled. Make sure to use host networking so that bonob can find the sonos devices (or provide a BONOB_SONOS_SEED_HOST)
|
Now within the LAN that contains the sonos devices run bonob the registration process.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker run \
|
docker run \
|
||||||
-e BONOB_URL=https://my-server.example.com/bonob \
|
|
||||||
-e BONOB_SONOS_DEVICE_DISCOVERY=true \
|
|
||||||
--network host \
|
--network host \
|
||||||
simojenki/bonob register
|
simojenki/bonob register https://my-server.example.com/bonob
|
||||||
```
|
```
|
||||||
|
|
||||||
### Running bonob and navidrome using docker-compose
|
### Running bonob and navidrome using docker-compose
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
version: "3"
|
version: "3"
|
||||||
services:
|
services:
|
||||||
|
|||||||
@@ -46,9 +46,10 @@
|
|||||||
"xpath-ts": "^1.3.13"
|
"xpath-ts": "^1.3.13"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
"clean": "rm -Rf build",
|
||||||
"build": "tsc",
|
"build": "tsc",
|
||||||
"dev": "BONOB_PORT=4000 nodemon ./src/app.ts",
|
"dev": "BONOB_PORT=4000 BONOB_URL=http://$(hostname):4000 BONOB_SONOS_SERVICE_NAME=bonobDev BONOB_SONOS_DEVICE_DISCOVERY=false BONOB_SONOS_AUTO_REGISTER=false nodemon ./src/app.ts",
|
||||||
"test": "jest",
|
"register-dev": "ts-node ./src/register.ts http://$(hostname):4000",
|
||||||
"client-test": "ts-node tests/bonob_client.ts"
|
"test": "jest"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
14
src/app.ts
14
src/app.ts
@@ -67,6 +67,10 @@ const app = server(
|
|||||||
true,
|
true,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
app.listen(config.port, () => {
|
||||||
|
logger.info(`Listening on ${config.port} available @ ${config.bonobUrl}`);
|
||||||
|
});
|
||||||
|
|
||||||
if (config.sonos.autoRegister) {
|
if (config.sonos.autoRegister) {
|
||||||
sonosSystem.register(bonob).then((success) => {
|
sonosSystem.register(bonob).then((success) => {
|
||||||
if (success) {
|
if (success) {
|
||||||
@@ -75,10 +79,12 @@ if (config.sonos.autoRegister) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
} else if(config.sonos.deviceDiscovery) {
|
||||||
|
sonosSystem.devices().then(devices => {
|
||||||
|
devices.forEach(d => {
|
||||||
|
logger.info(`Found device ${d.name}(${d.group}) @ ${d.ip}:${d.port}`)
|
||||||
|
})
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
app.listen(config.port, () => {
|
|
||||||
logger.info(`Listening on ${config.port} available @ ${config.bonobUrl}`);
|
|
||||||
});
|
|
||||||
|
|
||||||
export default app;
|
export default app;
|
||||||
|
|||||||
@@ -1,26 +1,15 @@
|
|||||||
import readConfig from "./config";
|
import registrar from "./registrar";
|
||||||
import logger from "./logger";
|
import { URLBuilder } from "./url_builder";
|
||||||
import sonos, { bonobService } from "./sonos";
|
|
||||||
|
|
||||||
const config = readConfig();
|
const params = process.argv.slice(2);
|
||||||
|
|
||||||
const bonob = bonobService(
|
if (params.length != 1) {
|
||||||
config.sonos.serviceName,
|
console.error("Usage: register [URL to bonob]");
|
||||||
config.sonos.sid,
|
process.exit(1);
|
||||||
config.bonobUrl,
|
}
|
||||||
"AppLink"
|
|
||||||
);
|
|
||||||
|
|
||||||
const sonosSystem = sonos(config.sonos.deviceDiscovery, config.sonos.seedHost);
|
const bonobUrl = new URLBuilder(params[0]!);
|
||||||
|
registrar(bonobUrl)().then((success) => {
|
||||||
sonosSystem.register(bonob).then((success) => {
|
if (success) console.log(`Successfully registered bonob @ ${bonobUrl} with sonos`);
|
||||||
if (success) {
|
else console.error(`Failed registering bonob @ ${bonobUrl} with sonos`);
|
||||||
logger.info(
|
});
|
||||||
`Successfully registered ${bonob.name}(SID:${bonob.sid}) with sonos`
|
|
||||||
);
|
|
||||||
process.exit(0);
|
|
||||||
} else {
|
|
||||||
logger.error(`Failed to register ${bonob.name}(SID:${bonob.sid}) with sonos!!`)
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|||||||
19
src/registrar.ts
Normal file
19
src/registrar.ts
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
import axios from "axios";
|
||||||
|
import logger from "./logger";
|
||||||
|
import sonos, { bonobService } from "./sonos";
|
||||||
|
import { URLBuilder } from "./url_builder";
|
||||||
|
|
||||||
|
export default (bonobUrl: URLBuilder) => async () => {
|
||||||
|
const about = bonobUrl.append({ pathname: "/about" });
|
||||||
|
logger.info(`Fetching bonob service about from ${about}`);
|
||||||
|
return axios
|
||||||
|
.get(about.href())
|
||||||
|
.then((res) => {
|
||||||
|
if (res.status == 200) return res.data;
|
||||||
|
else throw `Unexpected response status ${res.status} from ${about}`;
|
||||||
|
})
|
||||||
|
.then((about) =>
|
||||||
|
bonobService(about.service.name, about.service.sid, bonobUrl)
|
||||||
|
)
|
||||||
|
.then((bonobService) => sonos(true).register(bonobService));
|
||||||
|
};
|
||||||
@@ -101,6 +101,15 @@ function server(
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
app.get("/about", (_, res) => {
|
||||||
|
return res.send({
|
||||||
|
service: {
|
||||||
|
name: service.name,
|
||||||
|
sid: service.sid
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
app.post(REGISTER_ROUTE, (_, res) => {
|
app.post(REGISTER_ROUTE, (_, res) => {
|
||||||
sonos.register(service).then((success) => {
|
sonos.register(service).then((success) => {
|
||||||
if (success) {
|
if (success) {
|
||||||
|
|||||||
@@ -132,7 +132,7 @@ const setupDiscovery = (
|
|||||||
sonosSeedHost?: string
|
sonosSeedHost?: string
|
||||||
): Promise<boolean> => {
|
): Promise<boolean> => {
|
||||||
if (sonosSeedHost == undefined || sonosSeedHost == "") {
|
if (sonosSeedHost == undefined || sonosSeedHost == "") {
|
||||||
logger.info("Trying to auto discover sonos devices");
|
logger.info("Trying to discover sonos devices");
|
||||||
return manager.InitializeWithDiscovery(10);
|
return manager.InitializeWithDiscovery(10);
|
||||||
} else {
|
} else {
|
||||||
logger.info(`Trying to discover sonos devices using seed ${sonosSeedHost}`);
|
logger.info(`Trying to discover sonos devices using seed ${sonosSeedHost}`);
|
||||||
|
|||||||
@@ -307,6 +307,36 @@ describe("server", () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("/about", () => {
|
||||||
|
const sonos = {
|
||||||
|
register: jest.fn(),
|
||||||
|
};
|
||||||
|
const theService = aService({
|
||||||
|
name: "We can all live a life of service",
|
||||||
|
sid: 999,
|
||||||
|
});
|
||||||
|
const server = makeServer(
|
||||||
|
sonos as unknown as Sonos,
|
||||||
|
theService,
|
||||||
|
bonobUrl,
|
||||||
|
new InMemoryMusicService()
|
||||||
|
);
|
||||||
|
|
||||||
|
it("should report some information about the service", async () => {
|
||||||
|
const res = await request(server)
|
||||||
|
.get(bonobUrl.append({ pathname: "/about" }).path())
|
||||||
|
.send();
|
||||||
|
|
||||||
|
expect(res.status).toEqual(200);
|
||||||
|
expect(res.body).toEqual({
|
||||||
|
service: {
|
||||||
|
name: theService.name,
|
||||||
|
sid: theService.sid
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe("/register", () => {
|
describe("/register", () => {
|
||||||
const sonos = {
|
const sonos = {
|
||||||
register: jest.fn(),
|
register: jest.fn(),
|
||||||
@@ -322,7 +352,7 @@ describe("server", () => {
|
|||||||
new InMemoryMusicService()
|
new InMemoryMusicService()
|
||||||
);
|
);
|
||||||
|
|
||||||
describe("when is succesfull", () => {
|
describe("when is successful", () => {
|
||||||
it("should return a nice message", async () => {
|
it("should return a nice message", async () => {
|
||||||
sonos.register.mockResolvedValue(true);
|
sonos.register.mockResolvedValue(true);
|
||||||
|
|
||||||
@@ -338,7 +368,7 @@ describe("server", () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("when is unsuccesfull", () => {
|
describe("when is unsuccessful", () => {
|
||||||
it("should return a failure message", async () => {
|
it("should return a failure message", async () => {
|
||||||
sonos.register.mockResolvedValue(false);
|
sonos.register.mockResolvedValue(false);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user