musiccast-repairkit/README.md

222 lines
10 KiB
Markdown
Raw Normal View History

2021-03-31 22:02:46 +02:00
# MusicCast "repair kit" 🩹
2018-08-09 21:20:30 +02:00
[![Docker Hub](https://github.com/nicolabs/musiccast-repairkit/actions/workflows/dockerhub.yml/badge.svg)](https://hub.docker.com/r/nicolabs/musiccast-repairkit) [![npmjs repo](https://img.shields.io/npm/v/musiccast-repairkit)](https://npmjs.com/package/musiccast-repairkit) [![GitHub repo](https://img.shields.io/badge/GitHub-source-pink.svg?logo=github)](https://github.com/nicolabs/musiccast-repairkit) [![Buy us a tree](https://img.shields.io/badge/Plant%20trees-%F0%9F%8C%B3-lightgreen)](https://plant.treeware.earth/nicolabs/musiccast-repairkit)
2018-08-09 21:20:30 +02:00
2023-03-10 08:52:46 +01:00
This software implements missing features for your [Yamaha MusicCast©](https://usa.yamaha.com/products/contents/audio_visual/musiccast/index.html) devices by using their embedded Application Programming Interface (API).
2021-03-28 15:09:20 +02:00
2023-03-10 08:52:46 +01:00
You will have to run this program on an always-on machine, connected to the same WiFi / Ethernet nertwork as your MusicCast devices so that it can communicate with them.
The behavior is managed by enabling and configuring scenarios, each one doing a specific task. You can even code your own scenarios.
2021-03-28 15:28:22 +02:00
2021-03-31 21:42:02 +02:00
2023-03-10 08:52:46 +01:00
## Scenarios
2021-03-31 21:42:02 +02:00
2023-03-10 08:52:46 +01:00
Each scenario is implemented as a script, written in JavaScript (run with [NodeJs](https://nodejs.org/)).
2021-03-28 15:28:22 +02:00
There is no guide on how to develop your own scenario, but you may look at the existing scripts, which are easy to understand for any JavaScript programmer.
2023-03-10 08:52:46 +01:00
Basically they work by watching events over the network (e.g. volume or source change) and calling accordingly the API of the MusicCast devices.
2021-03-28 15:28:22 +02:00
2023-03-10 08:52:46 +01:00
Scenarios are already provided in the [scripts](./scripts) directory in this project, for the following use cases :
- [change the sound program when the source changes](#scenario-automatic-sound-program-depending-on-the-source)
- [synchronize the volume of several devices](#scenario-synchronize-volume-of-several-devices)
- [standby several devices together](scenario-standby-several-devices-together)
### Scenario 1 : Automatic sound program depending on the source
2021-03-28 15:28:22 +02:00
![Illustration : source buttons on remote](doc/source-buttons.png)
2021-06-08 13:57:12 +02:00
*This is the script that comes from the original project, [axelo/yamaha-sound-program-by-source](https://github.com/axelo/yamaha-sound-program-by-source).*
2021-03-28 15:28:22 +02:00
2023-03-10 08:52:46 +01:00
#### What it does
2021-03-28 15:28:22 +02:00
When the input source of your Yamaha receiver changes, the sound program and clear voice settings are automatically changed.
2023-03-10 08:52:46 +01:00
#### How to configure
Currently the following mappings from source to sound program are hard coded. You can change them by editing the script directly.
2021-03-28 15:28:22 +02:00
2021-03-31 21:42:02 +02:00
tv => tv_program with clear_voice enabled
bd_dvd => tv_program with clear_voice enabled
spotify => music with clear_voice disabled
airplay => music with clear_voice disabled
2021-03-28 15:28:22 +02:00
On the command line, use `-s scripts/audio-profile.js` to enable this script and `--audio-profile.source=<source_IP>` to set the hostname or IP address of the receiver.
2021-03-28 15:28:22 +02:00
Top-level options (e.g. `--source`) and configuration file are also valid (see [instructions below](#command-line-usage)).
2021-03-28 15:28:22 +02:00
### Scenario 2 : Synchronize volume of several devices
2021-03-28 15:28:22 +02:00
![Illustration : volume buttons on remote](doc/volume-buttons.png)
2023-03-10 08:52:46 +01:00
#### What it does
2021-03-28 15:28:22 +02:00
2023-03-10 08:52:46 +01:00
If you have a Yamaha MusicCast receiver (like *CRX N470D*) connected to ***wireless*** Yamaha MusicCast speakers (like a MusicCast 20 stereo pair), you may have noticed that **using the device's physical volume button or the IR remote will not update the volume of the wireless speakers**. Those hardware buttons only work with speakers physically wired to the CRX receiver.
Your only option to set the same volume to all connected devices is to use the Yahama MusicCast mobile app, which is far less user-friendly than the physical remote.
This script will solve this by listening to volume changes on a source device and applying them on one or more target devices.
#### How to configure
2021-03-28 15:28:22 +02:00
2021-03-31 21:42:02 +02:00
On the command line, use `-s scripts/sync-volume.js` to enable this script and use the following options :
- `--sync-volume.source=<source_IP>` sets the hostname or IP address of the *master* receiver
- `--sync-volume.target=<target_IP [target_IP [...]]>` lists the *slave* devices that will reflect the master's volume changes. You can separate them with a space or pass the option several times.
2021-03-28 15:28:22 +02:00
Top-level options (e.g. `--source`) and configuration file are also valid (see [instructions below](#command-line-usage)).
### Scenario 3 : Standby several devices together
2023-03-10 08:52:46 +01:00
#### What it does
2021-06-09 23:25:19 +02:00
It sometimes happens that wirelessly-linked devices don't go to standby mode or don't awake together with the main one.
2023-03-10 08:52:46 +01:00
It may be a bug or a network reliability issue or whatever, but it forces you to physically put them on/off.
2021-06-09 23:25:19 +02:00
2023-03-10 08:52:46 +01:00
This script will automatically force a given list of devices to power on or off together with the main device.
#### How to configure
2021-06-09 23:25:19 +02:00
On the command line, use `-s scripts/standby-together.js` to enable this script and the following options :
- `--standby-together.source=<source_IP>` sets the hostname or IP address of the *master* receiver
- `--standby-together.target=<target_IP [target_IP [...]]>` lists the *slave* devices that will follow the master's power status. You can separate them with a space or pass the option several times.
2021-06-09 23:25:19 +02:00
Top-level options (e.g. `--source`) and configuration file are also valid (see [instructions below](#command-line-usage)).
2021-06-09 23:25:19 +02:00
2021-06-08 13:57:12 +02:00
## Command line usage
> There are many ways to run this program ; the exact shape of the command line depends on how you run it : with [npm, node](#running-with-nodejs-npm), [docker](#running-with-docker) or another way.
> For instance if you run using *npx*, replace `musiccast-repairkit ...` in the commands below with `npx musiccast-repairkit ...`.
2021-03-31 21:42:02 +02:00
When running the program you need to specify which scenarios to run.
The scenarios are `.js` scripts which implement the use cases above.
2023-03-10 08:52:46 +01:00
Use the **`-s` command line option to specify which script(s) to load** ; for example :
musiccast-repairkit -s ./scripts/sync-volume.js --source=192.168.1.42 --target=192.168.1.43 --target=192.168.1.44
2018-08-09 21:20:30 +02:00
You can run several scenarios at the same time :
2023-03-10 08:52:46 +01:00
musiccast-repairkit -s ./scripts/sync-volume.js -s ./scripts/standby-together.js ...
You can pass all options on the command line, or use the **`--config` option to read them from a JSON file** ; example :
musiccast-repairkit -s ./scripts/sync-volume.js --config config.json
2023-03-10 08:52:46 +01:00
Contents of config.json :
2018-08-09 21:20:30 +02:00
2021-03-31 21:42:02 +02:00
```json
{
"sync-volume": {
"source": "192.168.1.42",
"target": [
"192.168.1.43",
"192.168.1.44"
]
}
}
2021-03-31 21:42:02 +02:00
```
2023-03-10 08:52:46 +01:00
You can define **generic options** at the top level and **scenario-specific options** under a prefix named after the script's name (its filename without extension).
For instance with `--source 1.2.3.4 --sync-volume.source 5.6.7.8`, `1.2.3.4` will be used as the *source* parameter by default but `5.6.7.8` will be used for the *sync-volume* scenario only.
This also works for the JSON configuration file.
2023-03-10 08:52:46 +01:00
You can pass those arguments multiple times or provide space-separated values if you need to.
2023-03-10 08:52:46 +01:00
The following **environment variables** may be specified before running `index.js` :
2018-08-09 21:20:30 +02:00
2023-03-10 08:52:46 +01:00
LOCAL_IP # The local IP address of this program, 0.0.0.0 could work in some setups
PORT # Port listening for events from the receiver, defaults to 41100
2021-03-29 13:18:27 +02:00
Example
PORT=44444 LOCAL_IP=192.168.1.187 musiccast-repairkit ...
2018-08-09 21:20:30 +02:00
## Running with Node.js / npm
You can run the program natively using [Node.js](https://nodejs.org).
2021-06-11 00:24:49 +02:00
You can get the package from [npmjs](https://npmjs.com/package/musiccast-repairkit) ; here is one way :
# Installs npx for npm < 5.2.0
npm install -g npx
# Run the program
npx musiccast-repairkit -s my-custom-scenario.js --config my-config.json
2021-06-08 13:57:12 +02:00
Or you can run from the sources directly :
# Get the sources
git clone https://github.com/nicolabs/musiccast-repairkit
cd musiccast-repairkit
# Install dependencies
npm install
# Run the program
node . -s my-custom-scenario.js --config my-config.json
## Running with Docker
Instead of running this program with _Node.js_ / _npm_ you can run it as a [Docker](https://hub.docker.com/r/nicolabs/musiccast-repairkit) container :
docker run -d --network=host nicolabs/musiccast-repairkit:1.1 -s ./scripts/standby-together.js --source 192.168.1.42 --target 192.168.1.43
See also [docker-compose.yml](docker-compose.yml) for a deployment template. It contains a sample *command* that you shall override to fit your needs.
2021-03-31 21:42:02 +02:00
You can edit it locally to reflect the IP addresses of your setup (or use a `.env` file or set environment variables).
It should not be necessary to define a `LOCAL_IP` environment variable as IP addresses inside the container will likely don't match the one of the host.
2023-03-10 08:52:46 +01:00
### Build & deploy Docker image
2021-03-29 13:18:27 +02:00
2021-03-31 21:42:02 +02:00
Build :
2021-03-29 13:18:27 +02:00
2021-03-31 21:42:02 +02:00
docker-compose build
2021-03-24 22:38:43 +01:00
2021-03-28 15:28:22 +02:00
Or build for multiple platforms :
2021-03-31 21:42:02 +02:00
docker buildx build --platform linux/amd64,linux/arm/v6,linux/arm/v7,linux/arm64/v8,linux/ppc64le,linux/s390x -t nicolabs/musiccast-repairkit .
2021-03-28 15:28:22 +02:00
Run locally :
2021-03-24 22:38:43 +01:00
2021-03-31 21:42:02 +02:00
docker-compose up --detach
2021-03-24 22:38:43 +01:00
2021-06-08 13:57:12 +02:00
Deploy on a swarm cluster :
2021-03-24 22:38:43 +01:00
2021-03-31 21:42:02 +02:00
docker stack deploy -c docker-compose.yml musiccast-repairkit
2021-03-24 22:38:43 +01:00
2021-03-31 21:42:02 +02:00
## Logging and debugging
2021-03-24 22:38:43 +01:00
There is an option `-l` to change the default logging level ; the most useful option might be `-l debug`.
2023-03-10 08:52:46 +01:00
Otherwise, logging is set in the [`logging.js`](logging.js) module : feel free to override it locally or in your custom Docker image.
2023-03-10 08:52:46 +01:00
There is a special `scripts/debug.js` script that does nothing but print debug informations. It is simply loaded as a scenario (you need to set log level to *debug* at least) :
musiccast-repairkit -s ./scripts/sync-volume.js ./scripts/debug.js -l debug --source=192.168.1.42 ...
2023-03-10 08:52:46 +01:00
Note : Node.Js natively allows to log network activity :
2021-03-24 22:38:43 +01:00
NODE_DEBUG="net" musiccast-repairkit ...
2021-03-24 22:38:43 +01:00
2023-03-10 08:52:46 +01:00
## References
2018-08-09 21:20:30 +02:00
2021-03-31 21:42:02 +02:00
- http://habitech.s3.amazonaws.com/PDFs/YAM/MusicCast/Yamaha%20MusicCast%20HTTP%20simplified%20API%20for%20ControlSystems.pdf
- https://www.pdf-archive.com/2017/04/21/yxc-api-spec-advanced/yxc-api-spec-advanced.pdf
- https://github.com/samvdb/php-musiccast-api
- [musiccast2mqtt, another implementation with MQTT, but old](https://github.com/ppt000/musiccast2mqtt) ([doc](https://musiccast2mqtt.readthedocs.io/en/latest/))
## Licence
This package is [Treeware](https://treeware.earth). If you use it in production, then we ask that you [**buy the world a tree**](https://plant.treeware.earth/nicolabs/musiccast-repairkit) to thank us for our work. By contributing to the Treeware forest youll be creating employment for local families and restoring wildlife habitats.