├── .all-contributorsrc
├── .github
├── CODE-OF-CONDUCT.md
├── CONTRIBUTING.md
├── Funding.yml
├── ISSUE_TEMPLATE
│ ├── config.yml
│ ├── documentation.md
│ └── template.md
├── pull_request_template.md
└── workflows
│ ├── generator.yml
│ ├── json-validation.yml
│ └── linter.yml
├── .gitignore
├── .markdownlint.json
├── .yamllint.yml
├── LICENSE
├── README.md
├── docs
├── .gitignore
├── 404.html
├── Gemfile
├── Gemfile.lock
├── _config.yml
├── _data
│ ├── colors.json
│ ├── metadata.json
│ └── projects.json
├── _includes
│ ├── apps.html
│ ├── libraries.html
│ └── project-card.html
├── _sass
│ └── custom
│ │ └── custom.scss
├── developers.md
├── docker-compose.yml
├── documentation.json
├── index.md
├── metadata.md
├── music-services.json
├── music-services.md
├── projects.md
├── schema
│ ├── author.json
│ ├── documentation.json
│ ├── metadata.json
│ ├── projects.json
│ └── template.json
├── services
│ ├── alarm-clock.md
│ ├── audio-in.md
│ ├── av-transport.md
│ ├── connection-manager.md
│ ├── content-directory.md
│ ├── device-properties.md
│ ├── group-management.md
│ ├── group-rendering-control.md
│ ├── ht-control.md
│ ├── index.md
│ ├── music-services.md
│ ├── q-play.md
│ ├── queue.md
│ ├── rendering-control.md
│ ├── system-properties.md
│ ├── virtual-line-in.md
│ └── zone-group-topology.md
└── sonos-communication.md
└── generator
└── sonos-docs
├── .editorconfig
├── .eslintignore
├── .eslintrc
├── .gitignore
├── README.md
├── bin
├── run
└── run.cmd
├── data
├── sonos-S1-2.json
├── sonos-S13-2.json
├── sonos-S14-2.json
├── sonos-S18-2.json
├── sonos-S19-2.json
├── sonos-S21-2.json
├── sonos-S27-2.json
├── sonos-S3-2.json
├── sonos-S33-2.json
├── sonos-S38-2.json
├── sonos-S5-1.json
├── sonos-S6-2.json
├── sonos-S9-2.json
└── sonos-Sub-2.json
├── package-lock.json
├── package.json
├── src
├── commands
│ ├── combine.ts
│ ├── generate.ts
│ ├── musicservices.ts
│ └── services.ts
├── helpers
│ ├── array-helper.ts
│ └── string-helper.ts
├── index.ts
└── models
│ ├── author.ts
│ ├── extended-sonos-description.ts
│ ├── sonos-device.ts
│ ├── sonos-discovery-info.ts
│ ├── sonos-service-action.ts
│ ├── sonos-service-documentation.ts
│ ├── sonos-service-error.ts
│ ├── sonos-service.ts
│ ├── sonos-state-variable.ts
│ └── template.ts
├── templates
├── docs
│ ├── service.hbs
│ ├── services-index.hbs
│ └── template.json
└── node
│ ├── README.md
│ ├── service.hbs
│ └── template.json
└── tsconfig.json
/.all-contributorsrc:
--------------------------------------------------------------------------------
1 | {
2 | "projectName": "sonos-api-docs",
3 | "projectOwner": "svrooij",
4 | "repoType": "github",
5 | "repoHost": "https://github.com",
6 | "files": [
7 | "README.md",
8 | "docs/index.md"
9 | ],
10 | "imageSize": 100,
11 | "commit": true,
12 | "commitConvention": "eslint",
13 | "contributors": [
14 | {
15 | "login": "svrooij",
16 | "name": "Stephan van Rooij",
17 | "avatar_url": "https://avatars2.githubusercontent.com/u/1292510?v=4",
18 | "profile": "https://svrooij.nl",
19 | "contributions": [
20 | "code",
21 | "doc",
22 | "ideas",
23 | "maintenance"
24 | ]
25 | },
26 | {
27 | "login": "hklages",
28 | "name": "H. Klages",
29 | "avatar_url": "https://avatars3.githubusercontent.com/u/17273119?v=4",
30 | "profile": "https://github.com/hklages",
31 | "contributions": [
32 | "doc"
33 | ]
34 | },
35 | {
36 | "login": "sschuberth",
37 | "name": "Sebastian Schuberth",
38 | "avatar_url": "https://avatars0.githubusercontent.com/u/349154?v=4",
39 | "profile": "https://github.com/sschuberth",
40 | "contributions": [
41 | "doc"
42 | ]
43 | },
44 | {
45 | "login": "jkossis",
46 | "name": "Jason Kossis",
47 | "avatar_url": "https://avatars.githubusercontent.com/u/1247832?v=4",
48 | "profile": "https://github.com/jkossis",
49 | "contributions": [
50 | "doc"
51 | ]
52 | }
53 | ],
54 | "contributorsPerLine": 7,
55 | "skipCi": true
56 | }
57 |
--------------------------------------------------------------------------------
/.github/CODE-OF-CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Code of Conduct
2 |
3 | ## Our Standards
4 |
5 | Examples of behavior that contributes to creating a positive environment
6 | include:
7 |
8 | * Using welcoming and inclusive language
9 | * Being respectful of differing viewpoints and experiences
10 | * Gracefully accepting constructive criticism
11 | * Focusing on what is best for the community
12 | * Showing empathy towards other community members
13 |
14 | Examples of unacceptable behavior by participants include:
15 |
16 | * The use of sexualized language or imagery and unwelcome sexual attention or
17 | advances
18 | * Trolling, insulting/derogatory comments, and personal or political attacks
19 | * Public or private harassment
20 | * Publishing others' private information, such as a physical or electronic
21 | address, without explicit permission
22 | * Other conduct which could reasonably be considered inappropriate in a
23 | professional setting
24 |
25 | ## Our Responsibilities
26 |
27 | Project maintainers are responsible for clarifying the standards of acceptable
28 | behavior and are expected to take appropriate and fair corrective action in
29 | response to any instances of unacceptable behavior.
30 |
31 | Project maintainers have the right and responsibility to remove, edit, or
32 | reject comments, commits, code, wiki edits, issues, and other contributions
33 | that are not aligned to this Code of Conduct, or to ban temporarily or
34 | permanently any contributor for other behaviors that they deem inappropriate,
35 | threatening, offensive, or harmful.
36 |
37 | ## Scope
38 |
39 | This Code of Conduct applies both within project spaces and in public spaces
40 | when an individual is representing the project or its community. Examples of
41 | representing a project or community include using an official project e-mail
42 | address, posting via an official social media account, or acting as an appointed
43 | representative at an online or offline event. Representation of a project may be
44 | further defined and clarified by project maintainers.
45 |
46 | ## Enforcement
47 |
48 | Instances of abusive, harassing, or otherwise unacceptable behavior may be
49 | reported by contacting the project team at sonos [no-spam] svrooij.io. All
50 | complaints will be reviewed and investigated and will result in a response that
51 | is deemed necessary and appropriate to the circumstances. The project team is
52 | obligated to maintain confidentiality with regard to the reporter of an incident.
53 | Further details of specific enforcement policies may be posted separately.
54 |
55 | Project maintainers who do not follow or enforce the Code of Conduct in good
56 | faith may face temporary or permanent repercussions as determined by other
57 | members of the project's leadership.
58 |
59 | ## Attribution
60 |
61 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
62 | available at [contributor-covenant.org/version/1/4/code-of-conduct.html](https://www.contributor-covenant.org/version/1/4/code-of-conduct.html)
63 |
64 | [homepage]: https://www.contributor-covenant.org
65 |
66 | For answers to common questions about this code of conduct, see
67 | [contributor-covenant.org/faq](https://www.contributor-covenant.org/faq)
68 |
--------------------------------------------------------------------------------
/.github/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing to Sonos API Docs
2 |
3 | A big welcome and thank you for considering contributing to this open source documentation on Sonos! It’s people like you that make it a reality for users in our community.
4 |
5 | Reading and following these guidelines will help us make the contribution process easy and effective for everyone involved. It also communicates that you agree to respect the time of the developers managing and developing these open source projects. In return, we will reciprocate that respect by addressing your issue, assessing changes, and helping you finalize your pull requests.
6 |
7 | ## Quicklinks
8 |
9 | * [Code of Conduct](#code-of-conduct)
10 | * [Getting Started](#getting-started)
11 | - [Issues](#issues)
12 | - [Pull Requests](#pull-requests)
13 | * [Getting Help](#getting-help)
14 | * [Sponsoring](sponsoring)
15 |
16 | ## Code of Conduct
17 |
18 | We take our open source community seriously and hold ourselves and other contributors to high standards of communication. By participating and contributing to this project, you agree to uphold our [Code of Conduct](https://github.com/svrooij/sonos-api-docs/blob/main/.github/CODE-OF-CONDUCT.md).
19 |
20 | ## Getting Started
21 |
22 | Contributions are made to this repo via Issues and Pull Requests (PRs). A few general guidelines that cover both:
23 |
24 | - Search for existing Issues and PRs before creating your own.
25 | - We work hard to makes sure issues are handled in a timely manner but, depending on the impact, it could take a while to investigate the root cause. A friendly ping in the comment thread to the submitter or a contributor can help draw attention if your issue is blocking.
26 | - If you've never contributed before, see [the first timer's guide on our blog](https://auth0.com/blog/a-first-timers-guide-to-an-open-source-project/) for resources and tips on how to get started.
27 |
28 | ### Issues
29 |
30 | Issues should be used to report problems with the documentation, request a new feature, or to discuss potential changes before a PR is created.
31 |
32 |
33 |
34 | If you find an Issue that addresses the problem you're having, please add your own reproduction information to the existing issue rather than creating a new one. Adding a [reaction](https://github.blog/2016-03-10-add-reactions-to-pull-requests-issues-and-comments/) can also help be indicating to our maintainers that a particular problem is affecting more than just the reporter.
35 |
36 | ### Pull Requests
37 |
38 | PRs to our libraries are always welcome and can be a quick way to get your fix or improvement slated for the next release. In general, PRs should:
39 |
40 | - Only fix/add the functionality in question **OR** address wide-spread whitespace/style issues, not both.
41 | - If you changed the [documentation.json](https://sonos.svrooij.io/developers.html#documentationjson) or any device discovery files, be sure to also [regenerate](https://sonos.svrooij.io/developers.html#regenerate-documentation) the services.
42 | - Be sure to [preview](https://sonos.svrooij.io/developers.html#live-preview-on-local-machine) your changes in the resulting webpage.
43 | - Be accompanied by a complete Pull Request template (loaded automatically when a PR is created).
44 |
45 | For changes that address core functionality or would require breaking changes (e.g. a major release), it's best to open an Issue to discuss your proposal first. This is not required but can save time creating and reviewing changes.
46 |
47 | In general, we follow the ["fork-and-pull" Git workflow](https://github.com/susam/gitpr)
48 |
49 | 1. Fork the repository to your own Github account
50 | 2. Clone the project to your machine
51 | 3. Create a branch locally with a succinct but descriptive name
52 | 4. Commit changes to the branch
53 | 5. Following any formatting and testing guidelines specific to this repo
54 | 6. Push changes to your fork
55 | 7. Open a PR in our repository and follow the PR template so that we can efficiently review the changes.
56 |
57 | ## Sponsoring
58 |
59 | [![Support me on Github][badge_sponsor]][link_sponsor]
60 |
61 | You cannot only contribute by spending some time to document stuff or the help users with his/her issues, you can also sponsor me, so I can spend time on my open-source projects like these.
62 |
63 | [badge_issues]: https://img.shields.io/github/issues/svrooij/sonos-api-docs
64 | [badge_sponsor]: https://img.shields.io/badge/Sponsor-on%20Github-red
65 |
66 | [link_sponsor]: https://github.com/sponsors/svrooij
67 | [link_issues]: https://github.com/svrooij/sonos-api-docs/issues
68 |
--------------------------------------------------------------------------------
/.github/Funding.yml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | github: svrooij
4 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/config.yml:
--------------------------------------------------------------------------------
1 | blank_issues_enabled: false
2 | contact_links:
3 | - name: Questions
4 | url: https://github.com/svrooij/sonos-api-docs/discussions/categories/q-a
5 | about: Please ask and answer questions here.
6 | - name: All discussions
7 | url: https://github.com/svrooij/sonos-api-docs/discussions
8 | about: General discussions about the Sonos API.
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/documentation.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Documenation improvement
3 | about: Use this if some action isn't documented correctly
4 | title: 'Documentation: '
5 | labels: docs
6 | assignees: ''
7 |
8 | ---
9 |
10 | ### System info
11 |
12 | - Sonos version (S1 or S2):
13 | - Software version:
14 |
15 | ### Service details
16 |
17 |
18 |
19 | - Service name:
20 | - Action name(s):
21 |
22 | ### Link to current documentation
23 |
24 |
25 |
26 | ### Proposed change
27 |
28 |
29 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/template.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Template improvement
3 | about: Use this if you want to suggest a change to a template
4 | title: 'Template: '
5 | labels: template
6 | assignees: ''
7 |
8 | ---
9 |
10 | ### Template details
11 |
12 |
19 |
20 | - What template (`sonos-ts` / `docs`):
21 | - What part of the template:
22 | - Current source URL:
23 | - Current output URL:
24 |
25 | ### Proposed change
26 |
27 |
28 |
29 | ### Additional context
30 |
31 |
32 |
--------------------------------------------------------------------------------
/.github/pull_request_template.md:
--------------------------------------------------------------------------------
1 | # Your title here
2 |
3 | ## Description
4 |
5 | Please describe your pull request.
6 |
7 | ## Your checklist for this pull request
8 |
9 | 🚨 Please review the [guidelines for contributing](https://github.com/svrooij/sonos-api-docs/blob/main/.github/CONTRIBUTING.md) to this repository.
10 |
11 | - [ ] Make sure you are requesting to **pull a topic/feature/bugfix branch** (right side). Don't request your main!
12 | - [ ] Make sure you are making a pull request against the **main branch** (left side). Also you should start *your branch* off *svrooij/sonos-api-docs/main*.
13 | - [ ] Check your code additions will fail neither code linting checks nor unit test. (mine sometimes also fail, will probably ignore the lint failures)
14 | - [ ] If you changed the **documentation.json** be sure to also [regenerate](https://sonos.svrooij.io/developers.html#regenerate-documentation) the services files.
15 | - [ ] The `docs/services/index.md` and the `docs/services/*.md` files should not be manually changed, only with the generator.
16 |
17 | 💔 Thank you!
--------------------------------------------------------------------------------
/.github/workflows/generator.yml:
--------------------------------------------------------------------------------
1 | on:
2 | workflow_dispatch:
3 | push:
4 | branches:
5 | - main
6 | - ci-build
7 | paths:
8 | - '.github/workflows/generator.yml'
9 | - 'generator/sonos-docs/src/**/*.ts'
10 | - 'generator/sonos-docs/.releaserc'
11 |
12 | pull_request:
13 | branches:
14 | - main
15 | paths:
16 | - '.github/workflows/generator.yml'
17 | - 'generator/sonos-docs/src/**/*.ts'
18 |
19 | jobs:
20 | test:
21 | name: 'Build and test on Node v${{ matrix.node }}'
22 | runs-on: ubuntu-latest
23 | strategy:
24 | matrix:
25 | node: [16, 18]
26 | defaults:
27 | run:
28 | working-directory: generator/sonos-docs
29 | steps:
30 | - uses: actions/checkout@v4
31 | - uses: actions/setup-node@v4
32 | with:
33 | node-version: ${{ matrix.node }}
34 | - name: Install depencencies
35 | run: npm ci
36 | - name: Build library
37 | run: npm run prepack
38 |
39 | release:
40 | name: 'Release generator'
41 | needs: [test]
42 | runs-on: ubuntu-latest
43 | if: github.event_name != 'pull_request'
44 | defaults:
45 | run:
46 | working-directory: generator/sonos-docs
47 | steps:
48 | - uses: actions/checkout@v4
49 | - uses: actions/setup-node@v4
50 | with:
51 | node-version: 16
52 | - name: Install depencencies
53 | run: npm ci
54 | - name: Semantic Release
55 | uses: cycjimmy/semantic-release-action@v4
56 | id: semantic
57 | with:
58 | working_directory: generator/sonos-docs
59 | env:
60 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
61 | NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
62 | - name: Setup node for Github Registry
63 | if: steps.semantic.outputs.new_release_published == 'true'
64 | uses: actions/setup-node@v4
65 | with:
66 | node-version: 16
67 | registry-url: 'https://npm.pkg.github.com'
68 | scope: 'svrooij'
69 | - name: Publish To GitHub Package Registry
70 | if: steps.semantic.outputs.new_release_published == 'true'
71 | run: |
72 | npm publish
73 | env:
74 | NODE_AUTH_TOKEN: ${{secrets.GITHUB_TOKEN}}
75 |
--------------------------------------------------------------------------------
/.github/workflows/json-validation.yml:
--------------------------------------------------------------------------------
1 | name: JSON validation
2 |
3 | on:
4 | push:
5 | branches:
6 | - main
7 | - beta
8 | paths:
9 | - 'docs/schema/*.json'
10 | - 'docs/documentation.json'
11 | - 'docs/_data/projects.json'
12 | - 'generator/sonos-docs/templates/**/template.json'
13 | - '.github/workflows/json-validation.yml'
14 | pull_request:
15 | branches:
16 | - main
17 |
18 | jobs:
19 | validate-docs:
20 | name: Validate JSON files
21 | runs-on: ubuntu-latest
22 | steps:
23 | - name: Checkout Code
24 | uses: actions/checkout@v4
25 | - name: Use node 16
26 | uses: actions/setup-node@v4
27 | with:
28 | node-version: 16
29 | - name: Install ajv-cli
30 | run: npm i -g ajv-cli
31 | - name: Validate docs/_data/projects.json
32 | run: ajv validate -d ./docs/_data/projects.json -s ./docs/schema/projects.json -r ./docs/schema/author.json
33 | - name: Validate docs/documentation.json
34 | run: ajv validate -s ./docs/schema/documentation.json -d ./docs/documentation.json
35 | - name: Validate template json files
36 | run: ajv validate -s ./docs/schema/template.json -d "./generator/sonos-docs/templates/**/template.json" -r ./docs/schema/author.json
37 |
--------------------------------------------------------------------------------
/.github/workflows/linter.yml:
--------------------------------------------------------------------------------
1 | ---
2 | ###########################
3 | ###########################
4 | ## Linter GitHub Actions ##
5 | ###########################
6 | ###########################
7 | name: Lint Code Base
8 |
9 | #
10 | # Documentation:
11 | # https://help.github.com/en/articles/workflow-syntax-for-github-actions
12 | #
13 |
14 | #############################
15 | # Start the job on all push #
16 | #############################
17 | on:
18 | push:
19 | #branches-ignore: [master]
20 | # Remove the line above to run when pushing to master
21 | pull_request:
22 | branches: [main]
23 |
24 | ###############
25 | # Set the Job #
26 | ###############
27 | jobs:
28 | build:
29 | # Name the Job
30 | name: Lint Code Base
31 | # Set the agent to run on
32 | runs-on: ubuntu-latest
33 |
34 | ##################
35 | # Load all steps #
36 | ##################
37 | steps:
38 | ##########################
39 | # Checkout the code base #
40 | ##########################
41 | - name: Checkout Code
42 | uses: actions/checkout@v4
43 | with:
44 | # Full git history is needed to get list of changed files
45 | fetch-depth: 0
46 |
47 | ################################
48 | # Run Linter against code base #
49 | ################################
50 | - name: Lint Code Base
51 | uses: github/super-linter/slim@v5
52 | env:
53 | VALIDATE_ALL_CODEBASE: false
54 | VALIDATE_JAVASCRIPT_STANDARD: false
55 | VALIDATE_TYPESCRIPT_STANDARD: false
56 | VALIDATE_JSCPD: false
57 | VALIDATE_HTML: false
58 | FILTER_REGEX_EXCLUDE: .*docs/services/*.md
59 | DEFAULT_BRANCH: main
60 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
61 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 | lerna-debug.log*
8 |
9 | # Diagnostic reports (https://nodejs.org/api/report.html)
10 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
11 |
12 | # Runtime data
13 | pids
14 | *.pid
15 | *.seed
16 | *.pid.lock
17 |
18 | # Directory for instrumented libs generated by jscoverage/JSCover
19 | lib-cov
20 |
21 | # Coverage directory used by tools like istanbul
22 | coverage
23 | *.lcov
24 |
25 | # nyc test coverage
26 | .nyc_output
27 |
28 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
29 | .grunt
30 |
31 | # Bower dependency directory (https://bower.io/)
32 | bower_components
33 |
34 | # node-waf configuration
35 | .lock-wscript
36 |
37 | # Compiled binary addons (https://nodejs.org/api/addons.html)
38 | build/Release
39 |
40 | # Dependency directories
41 | node_modules/
42 | jspm_packages/
43 |
44 | # TypeScript v1 declaration files
45 | typings/
46 |
47 | # TypeScript cache
48 | *.tsbuildinfo
49 |
50 | # Optional npm cache directory
51 | .npm
52 |
53 | # Optional eslint cache
54 | .eslintcache
55 |
56 | # Microbundle cache
57 | .rpt2_cache/
58 | .rts2_cache_cjs/
59 | .rts2_cache_es/
60 | .rts2_cache_umd/
61 |
62 | # Optional REPL history
63 | .node_repl_history
64 |
65 | # Output of 'npm pack'
66 | *.tgz
67 |
68 | # Yarn Integrity file
69 | .yarn-integrity
70 |
71 | # dotenv environment variables file
72 | .env
73 | .env.test
74 |
75 | # parcel-bundler cache (https://parceljs.org/)
76 | .cache
77 |
78 | # Next.js build output
79 | .next
80 |
81 | # Nuxt.js build / generate output
82 | .nuxt
83 | dist
84 |
85 | # Gatsby files
86 | .cache/
87 | # Comment in the public line in if your project uses Gatsby and *not* Next.js
88 | # https://nextjs.org/blog/next-9-1#public-directory-support
89 | # public
90 |
91 | # vuepress build output
92 | .vuepress/dist
93 |
94 | # Serverless directories
95 | .serverless/
96 |
97 | # FuseBox cache
98 | .fusebox/
99 |
100 | # DynamoDB Local files
101 | .dynamodb/
102 |
103 | # TernJS port file
104 | .tern-port
105 |
106 | # .new-version file used in Github workflow
107 | .new-version
108 |
--------------------------------------------------------------------------------
/.markdownlint.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://raw.githubusercontent.com/DavidAnson/markdownlint/main/schema/markdownlint-config-schema.json",
3 | "fenced-code-language": false,
4 | "MD013": false,
5 | "MD025": false
6 | }
7 |
--------------------------------------------------------------------------------
/.yamllint.yml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | extends: default
4 |
5 | rules:
6 | document-start: disable # don't bother me with this rule
7 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020 Stephan van Rooij
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Unofficial Sonos docs
2 |
3 | [![Sonos API documentation][badge_sonos-docs]][link_sonos-docs]
4 | [![Github Issues][badge_issues]][link_issues]
5 | [![Sonos2mqtt][badge_sonos-mqtt]][link_sonos-mqtt]
6 | [![Sonos cli][badge_sonos-cli]][link_sonos-cli]
7 | [![Sonos typescript this library][badge_sonos-typescript]][link_sonos-typescript]
8 |
9 | [![Support me on Github][badge_sponsor]][link_sponsor]
10 | [![Follow on Twitter][badge_twitter]][link_twitter]
11 |
12 | Sonos API documentation for the local UPNP API and a [generator](https://github.com/svrooij/sonos-api-docs/tree/main/generator/sonos-docs) to generate clients and documentation based on service discovery
13 |
14 | This library is in no way connected to [Sonos](//en.wikipedia.org/wiki/Sonos). It's just a set of text files to document a hidden and **unsupported** API.
15 |
16 | ## Documentation
17 |
18 | Check-out the (generated) documentation about all the SONOS UPNP services [svrooij.io/sonos-api-docs/services/](https://sonos.svrooij.io/services/)
19 |
20 | [![Sonos API documentation][badge_sonos-docs]][link_sonos-docs]
21 |
22 | [Read documentation](https://sonos.svrooij.io/)
23 |
24 | ### Manually documented
25 |
26 | The [sonos services](https://sonos.svrooij.io/services/) have no documentation, that is why we manually created a [documentation.json](https://github.com/svrooij/sonos-api-docs/blob/main/docs/documentation.json) file. To easily add documentation to all services (that are generated with the generator). And it's json so you can easily use it yourself.
27 |
28 | ### Device discovery files
29 |
30 | You can use the generator to generate your own discovery files, but we also have the files available for download.
31 |
32 | | Player | Discovery file(s) |
33 | | ------ | ----------------- |
34 | | Sonos Play:1 | [S2](https://github.com/svrooij/sonos-api-docs/raw/main/generator/sonos-docs/data/sonos-S1-2.json) |
35 | | Sonos Play:3 | [S2](https://github.com/svrooij/sonos-api-docs/raw/main/generator/sonos-docs/data/sonos-S3-2.json) |
36 | | Sonos Play:5 (new) | [S2](https://github.com/svrooij/sonos-api-docs/raw/main/generator/sonos-docs/data/sonos-S6-2.json) |
37 | | Sonos Playbar | [S2](https://github.com/svrooij/sonos-api-docs/raw/main/generator/sonos-docs/data/sonos-S9-2.json) |
38 | | Sonos One | [S2](https://github.com/svrooij/sonos-api-docs/raw/main/generator/sonos-docs/data/sonos-S13-2.json) |
39 | | Sonos One (mic) | [S2](https://github.com/svrooij/sonos-api-docs/raw/main/generator/sonos-docs/data/sonos-S18-2.json) |
40 | | Sonos Beam | [S2](https://github.com/svrooij/sonos-api-docs/raw/main/generator/sonos-docs/data/sonos-S14-2.json) |
41 | | Sonos Roam | [S2](https://github.com/svrooij/sonos-api-docs/raw/main/generator/sonos-docs/data/sonos-S27-2.json) |
42 | | Sonos Sub | [S2](https://github.com/svrooij/sonos-api-docs/raw/main/generator/sonos-docs/data/sonos-Sub-2.json) |
43 | | SYMFONISK Bookshelf| [S2](https://github.com/svrooij/sonos-api-docs/raw/main/generator/sonos-docs/data/sonos-S21-2.json) |
44 | | Sonos Play:5 (old) | [S1](https://github.com/svrooij/sonos-api-docs/raw/main/generator/sonos-docs/data/sonos-S5-1.json) |
45 |
46 | These files together with the documentation file, are combined to a extensive JSON file, that is used as an input for the generator.
47 |
48 | ## Community
49 |
50 | If you have any [questions](https://github.com/svrooij/sonos-api-docs/discussions/categories/q-a) or you want to [show](https://github.com/svrooij/sonos-api-docs/discussions/categories/show-and-tell) your Sonos integration. Please join us in the [discussions](https://github.com/svrooij/sonos-api-docs/discussions) tab on this repository.
51 |
52 | ## Contributors ✨
53 |
54 |
55 | [](#contributors-)
56 |
57 |
58 | Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)):
59 |
60 |
61 |
62 |
63 |
71 |
72 |
73 |
74 |
75 |
76 |
77 | This project follows the [all-contributors](https://github.com/all-contributors/all-contributors)
78 | specification. Contributions of any kind welcome!
79 |
80 | [badge_issues]: https://img.shields.io/github/issues/svrooij/sonos-api-docs?style=for-the-badge
81 | [badge_sonos-cli]: https://img.shields.io/badge/sonos-cli-blue?style=for-the-badge
82 | [badge_sonos-docs]: https://img.shields.io/badge/sonos-api-blue?style=for-the-badge
83 | [badge_sonos-mqtt]: https://img.shields.io/badge/sonos-mqtt-blue?style=for-the-badge
84 | [badge_sonos-typescript]: https://img.shields.io/badge/sonos-typescript-blue?style=for-the-badge
85 | [badge_sponsor]: https://img.shields.io/github/sponsors/svrooij?logo=github&style=for-the-badge
86 | [badge_twitter]: https://img.shields.io/twitter/follow/svrooij?logo=twitter&style=for-the-badge
87 |
88 | [link_sponsor]: https://github.com/sponsors/svrooij
89 | [link_issues]: https://github.com/svrooij/sonos-api-docs/issues
90 | [link_sonos-cli]: https://github.com/svrooij/sonos-cli
91 | [link_sonos-docs]: https://sonos.svrooij.io/
92 | [link_sonos-mqtt]: https://sonos2mqtt.svrooij.io/
93 | [link_sonos-typescript]: https://sonos-ts.svrooij.io/
94 | [link_twitter]: https://twitter.com/svrooij
95 |
--------------------------------------------------------------------------------
/docs/.gitignore:
--------------------------------------------------------------------------------
1 | _site
2 | .sass-cache
3 | .jekyll-metadata
4 | vendor
--------------------------------------------------------------------------------
/docs/404.html:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | ---
4 |
5 |
18 |
19 |
20 |
404
21 |
22 |
Page not found :(
23 |
The requested page could not be found.
24 |
25 |
--------------------------------------------------------------------------------
/docs/Gemfile:
--------------------------------------------------------------------------------
1 | source "https://rubygems.org"
2 |
3 | # Hello! This is where you manage which Jekyll version is used to run.
4 | # When you want to use a different version, change it below, save the
5 | # file and run `bundle install`. Run Jekyll with `bundle exec`, like so:
6 | #
7 | # bundle exec jekyll serve
8 | #
9 | # This will help ensure the proper Jekyll version is running.
10 | # Happy Jekylling!
11 | # gem "jekyll", "~> 3.8.5"
12 |
13 | # If you want to use GitHub Pages, remove the "gem "jekyll"" above and
14 | # uncomment the line below. To upgrade, run `bundle update github-pages`.
15 | gem "github-pages", group: :jekyll_plugins
16 |
17 | # If you have any plugins, put them here!
18 | group :jekyll_plugins do
19 | gem "jekyll-feed", "~> 0.6"
20 | end
21 |
22 | # Windows does not include zoneinfo files, so bundle the tzinfo-data gem
23 | gem "tzinfo-data", platforms: [:mingw, :mswin, :x64_mingw, :jruby]
24 |
25 | # Performance-booster for watching directories on Windows
26 | gem "wdm", "~> 0.1.0" if Gem.win_platform?
27 |
28 | gem "just-the-docs", "0.3.3"
29 | gem "jekyll-octicons"
30 | gem "jemoji"
31 |
--------------------------------------------------------------------------------
/docs/Gemfile.lock:
--------------------------------------------------------------------------------
1 | GEM
2 | remote: https://rubygems.org/
3 | specs:
4 | activesupport (6.1.7.6)
5 | concurrent-ruby (~> 1.0, >= 1.0.2)
6 | i18n (>= 1.6, < 2)
7 | minitest (>= 5.1)
8 | tzinfo (~> 2.0)
9 | zeitwerk (~> 2.3)
10 | addressable (2.8.6)
11 | public_suffix (>= 2.0.2, < 6.0)
12 | base64 (0.2.0)
13 | coffee-script (2.4.1)
14 | coffee-script-source
15 | execjs
16 | coffee-script-source (1.12.2)
17 | colorator (1.1.0)
18 | commonmarker (0.23.10)
19 | concurrent-ruby (1.2.3)
20 | dnsruby (1.70.0)
21 | simpleidn (~> 0.2.1)
22 | em-websocket (0.5.3)
23 | eventmachine (>= 0.12.9)
24 | http_parser.rb (~> 0)
25 | ethon (0.16.0)
26 | ffi (>= 1.15.0)
27 | eventmachine (1.2.7)
28 | execjs (2.9.1)
29 | faraday (2.8.1)
30 | base64
31 | faraday-net_http (>= 2.0, < 3.1)
32 | ruby2_keywords (>= 0.0.4)
33 | faraday-net_http (3.0.2)
34 | ffi (1.16.3)
35 | forwardable-extended (2.6.0)
36 | gemoji (4.1.0)
37 | github-pages (229)
38 | github-pages-health-check (= 1.18.2)
39 | jekyll (= 3.9.4)
40 | jekyll-avatar (= 0.8.0)
41 | jekyll-coffeescript (= 1.2.2)
42 | jekyll-commonmark-ghpages (= 0.4.0)
43 | jekyll-default-layout (= 0.1.5)
44 | jekyll-feed (= 0.17.0)
45 | jekyll-gist (= 1.5.0)
46 | jekyll-github-metadata (= 2.16.1)
47 | jekyll-include-cache (= 0.2.1)
48 | jekyll-mentions (= 1.6.0)
49 | jekyll-optional-front-matter (= 0.3.2)
50 | jekyll-paginate (= 1.1.0)
51 | jekyll-readme-index (= 0.3.0)
52 | jekyll-redirect-from (= 0.16.0)
53 | jekyll-relative-links (= 0.7.0)
54 | jekyll-remote-theme (= 0.4.3)
55 | jekyll-sass-converter (= 1.5.2)
56 | jekyll-seo-tag (= 2.8.0)
57 | jekyll-sitemap (= 1.4.0)
58 | jekyll-swiss (= 1.0.0)
59 | jekyll-theme-architect (= 0.2.0)
60 | jekyll-theme-cayman (= 0.2.0)
61 | jekyll-theme-dinky (= 0.2.0)
62 | jekyll-theme-hacker (= 0.2.0)
63 | jekyll-theme-leap-day (= 0.2.0)
64 | jekyll-theme-merlot (= 0.2.0)
65 | jekyll-theme-midnight (= 0.2.0)
66 | jekyll-theme-minimal (= 0.2.0)
67 | jekyll-theme-modernist (= 0.2.0)
68 | jekyll-theme-primer (= 0.6.0)
69 | jekyll-theme-slate (= 0.2.0)
70 | jekyll-theme-tactile (= 0.2.0)
71 | jekyll-theme-time-machine (= 0.2.0)
72 | jekyll-titles-from-headings (= 0.5.3)
73 | jemoji (= 0.13.0)
74 | kramdown (= 2.4.0)
75 | kramdown-parser-gfm (= 1.1.0)
76 | liquid (= 4.0.4)
77 | mercenary (~> 0.3)
78 | minima (= 2.5.1)
79 | nokogiri (>= 1.13.6, < 2.0)
80 | rouge (= 3.30.0)
81 | terminal-table (~> 1.4)
82 | github-pages-health-check (1.18.2)
83 | addressable (~> 2.3)
84 | dnsruby (~> 1.60)
85 | octokit (>= 4, < 8)
86 | public_suffix (>= 3.0, < 6.0)
87 | typhoeus (~> 1.3)
88 | html-pipeline (2.14.3)
89 | activesupport (>= 2)
90 | nokogiri (>= 1.4)
91 | http_parser.rb (0.8.0)
92 | i18n (1.14.1)
93 | concurrent-ruby (~> 1.0)
94 | jekyll (3.9.4)
95 | addressable (~> 2.4)
96 | colorator (~> 1.0)
97 | em-websocket (~> 0.5)
98 | i18n (>= 0.7, < 2)
99 | jekyll-sass-converter (~> 1.0)
100 | jekyll-watch (~> 2.0)
101 | kramdown (>= 1.17, < 3)
102 | liquid (~> 4.0)
103 | mercenary (~> 0.3.3)
104 | pathutil (~> 0.9)
105 | rouge (>= 1.7, < 4)
106 | safe_yaml (~> 1.0)
107 | jekyll-avatar (0.8.0)
108 | jekyll (>= 3.0, < 5.0)
109 | jekyll-coffeescript (1.2.2)
110 | coffee-script (~> 2.2)
111 | coffee-script-source (~> 1.12)
112 | jekyll-commonmark (1.4.0)
113 | commonmarker (~> 0.22)
114 | jekyll-commonmark-ghpages (0.4.0)
115 | commonmarker (~> 0.23.7)
116 | jekyll (~> 3.9.0)
117 | jekyll-commonmark (~> 1.4.0)
118 | rouge (>= 2.0, < 5.0)
119 | jekyll-default-layout (0.1.5)
120 | jekyll (>= 3.0, < 5.0)
121 | jekyll-feed (0.17.0)
122 | jekyll (>= 3.7, < 5.0)
123 | jekyll-gist (1.5.0)
124 | octokit (~> 4.2)
125 | jekyll-github-metadata (2.16.1)
126 | jekyll (>= 3.4, < 5.0)
127 | octokit (>= 4, < 7, != 4.4.0)
128 | jekyll-include-cache (0.2.1)
129 | jekyll (>= 3.7, < 5.0)
130 | jekyll-mentions (1.6.0)
131 | html-pipeline (~> 2.3)
132 | jekyll (>= 3.7, < 5.0)
133 | jekyll-octicons (19.8.0)
134 | jekyll (>= 3.6, < 5.0)
135 | octicons (= 19.8.0)
136 | jekyll-optional-front-matter (0.3.2)
137 | jekyll (>= 3.0, < 5.0)
138 | jekyll-paginate (1.1.0)
139 | jekyll-readme-index (0.3.0)
140 | jekyll (>= 3.0, < 5.0)
141 | jekyll-redirect-from (0.16.0)
142 | jekyll (>= 3.3, < 5.0)
143 | jekyll-relative-links (0.7.0)
144 | jekyll (>= 3.3, < 5.0)
145 | jekyll-remote-theme (0.4.3)
146 | addressable (~> 2.0)
147 | jekyll (>= 3.5, < 5.0)
148 | jekyll-sass-converter (>= 1.0, <= 3.0.0, != 2.0.0)
149 | rubyzip (>= 1.3.0, < 3.0)
150 | jekyll-sass-converter (1.5.2)
151 | sass (~> 3.4)
152 | jekyll-seo-tag (2.8.0)
153 | jekyll (>= 3.8, < 5.0)
154 | jekyll-sitemap (1.4.0)
155 | jekyll (>= 3.7, < 5.0)
156 | jekyll-swiss (1.0.0)
157 | jekyll-theme-architect (0.2.0)
158 | jekyll (> 3.5, < 5.0)
159 | jekyll-seo-tag (~> 2.0)
160 | jekyll-theme-cayman (0.2.0)
161 | jekyll (> 3.5, < 5.0)
162 | jekyll-seo-tag (~> 2.0)
163 | jekyll-theme-dinky (0.2.0)
164 | jekyll (> 3.5, < 5.0)
165 | jekyll-seo-tag (~> 2.0)
166 | jekyll-theme-hacker (0.2.0)
167 | jekyll (> 3.5, < 5.0)
168 | jekyll-seo-tag (~> 2.0)
169 | jekyll-theme-leap-day (0.2.0)
170 | jekyll (> 3.5, < 5.0)
171 | jekyll-seo-tag (~> 2.0)
172 | jekyll-theme-merlot (0.2.0)
173 | jekyll (> 3.5, < 5.0)
174 | jekyll-seo-tag (~> 2.0)
175 | jekyll-theme-midnight (0.2.0)
176 | jekyll (> 3.5, < 5.0)
177 | jekyll-seo-tag (~> 2.0)
178 | jekyll-theme-minimal (0.2.0)
179 | jekyll (> 3.5, < 5.0)
180 | jekyll-seo-tag (~> 2.0)
181 | jekyll-theme-modernist (0.2.0)
182 | jekyll (> 3.5, < 5.0)
183 | jekyll-seo-tag (~> 2.0)
184 | jekyll-theme-primer (0.6.0)
185 | jekyll (> 3.5, < 5.0)
186 | jekyll-github-metadata (~> 2.9)
187 | jekyll-seo-tag (~> 2.0)
188 | jekyll-theme-slate (0.2.0)
189 | jekyll (> 3.5, < 5.0)
190 | jekyll-seo-tag (~> 2.0)
191 | jekyll-theme-tactile (0.2.0)
192 | jekyll (> 3.5, < 5.0)
193 | jekyll-seo-tag (~> 2.0)
194 | jekyll-theme-time-machine (0.2.0)
195 | jekyll (> 3.5, < 5.0)
196 | jekyll-seo-tag (~> 2.0)
197 | jekyll-titles-from-headings (0.5.3)
198 | jekyll (>= 3.3, < 5.0)
199 | jekyll-watch (2.2.1)
200 | listen (~> 3.0)
201 | jemoji (0.13.0)
202 | gemoji (>= 3, < 5)
203 | html-pipeline (~> 2.2)
204 | jekyll (>= 3.0, < 5.0)
205 | just-the-docs (0.3.3)
206 | jekyll (>= 3.8.5)
207 | jekyll-seo-tag (~> 2.0)
208 | rake (>= 12.3.1, < 13.1.0)
209 | kramdown (2.4.0)
210 | rexml
211 | kramdown-parser-gfm (1.1.0)
212 | kramdown (~> 2.0)
213 | liquid (4.0.4)
214 | listen (3.8.0)
215 | rb-fsevent (~> 0.10, >= 0.10.3)
216 | rb-inotify (~> 0.9, >= 0.9.10)
217 | mercenary (0.3.6)
218 | mini_portile2 (2.8.5)
219 | minima (2.5.1)
220 | jekyll (>= 3.5, < 5.0)
221 | jekyll-feed (~> 0.9)
222 | jekyll-seo-tag (~> 2.1)
223 | minitest (5.22.1)
224 | nokogiri (1.13.10)
225 | mini_portile2 (~> 2.8.0)
226 | racc (~> 1.4)
227 | octicons (19.8.0)
228 | octokit (4.25.1)
229 | faraday (>= 1, < 3)
230 | sawyer (~> 0.9)
231 | pathutil (0.16.2)
232 | forwardable-extended (~> 2.6)
233 | public_suffix (5.0.4)
234 | racc (1.7.3)
235 | rake (13.0.6)
236 | rb-fsevent (0.11.2)
237 | rb-inotify (0.10.1)
238 | ffi (~> 1.0)
239 | rexml (3.2.6)
240 | rouge (3.30.0)
241 | ruby2_keywords (0.0.5)
242 | rubyzip (2.3.2)
243 | safe_yaml (1.0.5)
244 | sass (3.7.4)
245 | sass-listen (~> 4.0.0)
246 | sass-listen (4.0.0)
247 | rb-fsevent (~> 0.9, >= 0.9.4)
248 | rb-inotify (~> 0.9, >= 0.9.7)
249 | sawyer (0.9.2)
250 | addressable (>= 2.3.5)
251 | faraday (>= 0.17.3, < 3)
252 | simpleidn (0.2.1)
253 | unf (~> 0.1.4)
254 | terminal-table (1.8.0)
255 | unicode-display_width (~> 1.1, >= 1.1.1)
256 | typhoeus (1.4.1)
257 | ethon (>= 0.9.0)
258 | tzinfo (2.0.6)
259 | concurrent-ruby (~> 1.0)
260 | unf (0.1.4)
261 | unf_ext
262 | unf_ext (0.0.9.1)
263 | unicode-display_width (1.8.0)
264 | zeitwerk (2.6.13)
265 |
266 | PLATFORMS
267 | ruby
268 |
269 | DEPENDENCIES
270 | github-pages
271 | jekyll-feed (~> 0.6)
272 | jekyll-octicons
273 | jemoji
274 | just-the-docs (= 0.3.3)
275 | tzinfo-data
276 |
277 | BUNDLED WITH
278 | 2.0.2
279 |
--------------------------------------------------------------------------------
/docs/_config.yml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | title: Sonos API
4 | email: 1292510+svrooij@users.noreply.github.com
5 |
6 | baseurl: "/sonos-api-docs"
7 | url: "https://svrooij.io"
8 | twitter_username: svrooij
9 | github_username: svrooij
10 | repository: svrooij/sonos-api-docs
11 |
12 | # Build settings
13 | markdown: kramdown
14 | remote_theme: svrooij/just-the-docs@plausible
15 | plugins:
16 | - jekyll-feed
17 | - jekyll-octicons
18 | - jemoji
19 |
20 | # Enable or disable heading anchors
21 | heading_anchors: true
22 |
23 | # Aux links for the upper right navigation
24 | aux_links:
25 | "Repository":
26 | - "//github.com/svrooij/sonos-api-docs"
27 | "Sponsor @svrooij":
28 | - "//github.com/sponsors/svrooij/"
29 |
30 | # Footer content appears at the bottom of every page's main content
31 | footer_content: >
32 | Copyright © 2022 Stephan van Rooij.
33 | Distributed under
35 | MIT license.
36 |
37 | toc:
38 | max_levels: 2
39 |
40 | # Footer "Edit this page on GitHub" link text
41 | gh_edit_link: true # show or hide edit this page link
42 | gh_edit_link_text: "Source on Github"
43 | gh_edit_repository: "https://github.com/svrooij/sonos-api-docs"
44 | gh_edit_branch: "main/docs" # the branch that your docs is served from
45 | gh_edit_view_mode: "tree" # "tree" or "edit"
46 |
47 | plausible_domain: "sonos.svrooij.io"
48 |
--------------------------------------------------------------------------------
/docs/_data/metadata.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://sonos.svrooij.io/schema/metadata.json",
3 | "metadata": [
4 | {
5 | "service": 9,
6 | "name": "Spotify Album",
7 | "identifier": "spotify:album:{id}",
8 | "uri": "x-rincon-cpcontainer:1004206cspotify:album:{id}?sid=9&flags=8300&sn=7",
9 | "metadata": {
10 | "id": "0004206cspotify:album:{id}",
11 | "class": "object.container.album.musicAlbum",
12 | "didlDescription": "SA_RINCON2311_X_#Svc2311-0-Token"
13 | }
14 | },
15 | {
16 | "service": 9,
17 | "name": "Spotify Artist Radio",
18 | "identifier": "spotify:artistRadio:{id}",
19 | "uri": "x-sonosapi-radio:spotify:artistRadio:{id}?sid=9&flags=8300&sn=7",
20 | "metadata": {
21 | "id": "100c206cspotify:artistRadio:{id}",
22 | "title": "Artist Radio",
23 | "parentId": "10052064spotify:artist:{id}",
24 | "class": "object.item.audioItem.audioBroadcast.#artistRadio",
25 | "didlDescription": "SA_RINCON2311_X_#Svc2311-0-Token"
26 | },
27 | "sampleId": "72qVrKXRp9GeFQOesj0Pmv"
28 | },
29 | {
30 | "service": 9,
31 | "name": "Spotify Artist Top Tracks",
32 | "identifier": "spotify:artistTopTracks:{id}",
33 | "uri": "x-rincon-cpcontainer:100e206cspotify:artistTopTracks:{id}?sid=9&flags=8300&sn=7",
34 | "metadata": {
35 | "id": "100c206cspotify:artistTopTracks:{id}",
36 | "parentId": "10052064spotify:artist:{id}",
37 | "class": "object.container.playlistContainer",
38 | "didlDescription": "SA_RINCON2311_X_#Svc2311-0-Token"
39 | }
40 | },
41 | {
42 | "service": 9,
43 | "name": "Spotify Playlist",
44 | "identifier": "spotify:playlist:{id}",
45 | "uri": "x-rincon-cpcontainer:1006206cspotify:playlist:{id}?sid=9&flags=8300&sn=7",
46 | "metadata": {
47 | "id": "1006206cspotify:playlist:{id}",
48 | "parentId": "10fe2664playlists",
49 | "class": "object.container.playlistContainer",
50 | "didlDescription": "SA_RINCON2311_X_#Svc2311-0-Token"
51 | },
52 | "sampleId": "5HllTKEvYoHAwODZdwKw9W"
53 | },
54 | {
55 | "service": 9,
56 | "name": "Spotify Track",
57 | "identifier": "spotify:track:{id}",
58 | "uri": "x-sonos-spotify:spotify:track:{id}?sid=9&flags=8224&sn=7",
59 | "metadata": {
60 | "id": "spotify:track:{id}",
61 | "title": "",
62 | "class": "object.item.audioItem.musicTrack",
63 | "didlDescription": "SA_RINCON2311_X_#Svc2311-0-Token"
64 | },
65 | "sampleId": "3nDZHJ43uRF3fZGEMIjZ0b"
66 | },
67 | {
68 | "service": 9,
69 | "name": "Spotify User Playlist",
70 | "identifier": "spotify:user:{id}",
71 | "uri": "x-rincon-cpcontainer:1004206cspotify:user:{id}?sid=9&flags=8300&sn=7",
72 | "metadata": {
73 | "id": "10062a6cspotify:user:{id}",
74 | "parentId": "10082664playlists",
75 | "title": "User's playlist",
76 | "class": "object.container.playlistContainer",
77 | "didlDescription": "SA_RINCON2311_X_#Svc2311-0-Token"
78 | }
79 | }
80 |
81 | ]
82 | }
--------------------------------------------------------------------------------
/docs/_data/projects.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://sonos.svrooij.io/schema/projects.json",
3 | "apps": [
4 | {
5 | "name": "sonos2mqtt",
6 | "description": "Control sonos speakers from your mqtt server",
7 | "link": "https://sonos2mqtt.svrooij.io/",
8 | "language": "TypeScript",
9 | "repository": "https://github.com/svrooij/sonos2mqtt",
10 | "tags": ["mqtt", "home-automation"],
11 | "author": {
12 | "name": "Stephan van Rooij",
13 | "link": "https://svrooij.io/"
14 | },
15 | "usesGenerator": true
16 | },
17 | {
18 | "name": "sonos cli",
19 | "description": "Control your sonos speakers from the console.",
20 | "language": "TypeScript",
21 | "repository": "https://github.com/svrooij/sonos-cli",
22 | "tags": ["cli"],
23 | "author": {
24 | "name": "Stephan van Rooij",
25 | "link": "https://svrooij.io/"
26 | },
27 | "usesGenerator": true
28 | },
29 | {
30 | "name": "FHEM-sonos",
31 | "description": "GERMAN LANGUAGE: FHEM integration",
32 | "tags": ["FHEM"],
33 | "link": "https://wiki.fhem.de/wiki/SONOS",
34 | "usesGenerator": false
35 | },
36 | {
37 | "name": "Noson",
38 | "description": "(unofficial) Sonos controller for Linux",
39 | "tags": ["Noson", "Linux"],
40 | "language": "C++",
41 | "author": {
42 | "name": "Jean-Luc Barrière",
43 | "link": "https://github.com/janbar"
44 | },
45 | "link": "http://janbar.github.io/noson-app/",
46 | "repository": "https://github.com/janbar/noson-app",
47 | "usesGenerator": false
48 | },
49 | {
50 | "name": "Ronor - cli (cloud based)",
51 | "description": "Sonos CLI that uses the cloud, written in Rust",
52 | "link": "https://github.com/mlang/ronor",
53 | "tags": ["cli", "Ronor"],
54 | "language": "Rust",
55 | "author": {
56 | "name": "Mario Lang",
57 | "link": "https://github.com/mlang"
58 | },
59 | "repository": "https://github.com/mlang/ronor",
60 | "usesGenerator": false
61 | },
62 | {
63 | "name": "ioBroker.sonos",
64 | "description": "Sonos support for ioBroker",
65 | "link": "https://github.com/ioBroker/ioBroker.sonos",
66 | "repository": "https://github.com/ioBroker/ioBroker.sonos",
67 | "tags": ["ioBroker"],
68 | "language": "JavaScript",
69 | "usesGenerator": false
70 | },
71 | {
72 | "name": "Bonob",
73 | "description": "Custom sonos music service for self-hosted Navidrome",
74 | "link": "https://github.com/simojenki/bonob",
75 | "repository": "https://github.com/simojenki/bonob",
76 | "author": {
77 | "name": "Simon J",
78 | "link": "https://github.com/simojenki"
79 | },
80 | "tags": ["Navidrome"],
81 | "language": "TypeScript",
82 | "usesGenerator": false
83 | },
84 | {
85 | "name": "SoCo CLI",
86 | "description": "Powerful command line controller for Sonos",
87 | "link": "https://github.com/avantrec/soco-cli",
88 | "repository": "https://github.com/avantrec/soco-cli",
89 | "tags": ["cli"],
90 | "language": "Python",
91 | "usesGenerator": false
92 | }
93 | ],
94 | "libraries": [
95 | {
96 | "name": "@svrooij/sonos",
97 | "description": "The most feature complete sonos library for node and TypeScript, since it uses a generator to create all the service classes",
98 | "link": "http://sonos-ts.svrooij.io/",
99 | "repository": "https://github.com/svrooij/node-sonos-ts",
100 | "language": "TypeScript",
101 | "tags": ["typescript", "node"],
102 | "author": {
103 | "name": "Stephan van Rooij",
104 | "link": "https://svrooij.io/"
105 | },
106 | "usesGenerator": true
107 | },
108 | {
109 | "name": "Sonos-net",
110 | "description": "Sonos library for dotnet core, it uses the generator to create all the service classes",
111 | "repository": "https://github.com/svrooij/sonos-net",
112 | "language": "C#",
113 | "tags": ["dotnet", "csharp"],
114 | "author": {
115 | "name": "Stephan van Rooij",
116 | "link": "https://svrooij.io/"
117 | },
118 | "usesGenerator": true
119 | },
120 | {
121 | "name": "sonos",
122 | "description": "Node library to control your sonos speakers.",
123 | "repository": "https://github.com/bencevans/node-sonos",
124 | "language": "JavaScript",
125 | "author": {
126 | "name": "Ben Evans",
127 | "link": "https://github.com/bencevans/"
128 | },
129 | "usesGenerator": false
130 | },
131 | {
132 | "name": "SoCo",
133 | "description": "Python library to control your sonos speakers",
134 | "link": "https://soco.readthedocs.io/en/latest/index.html",
135 | "repository": "https://github.com/SoCo/SoCo",
136 | "language": "Python",
137 | "author": {
138 | "name": "Rahim Sonawalla",
139 | "link": "https://github.com/rahims"
140 | },
141 | "usesGenerator": false
142 | },
143 | {
144 | "name": "duncan3dc-php-sonos",
145 | "description": "PHP library for interacting with Sonos speakers.",
146 | "repository": "https://github.com/duncan3dc/sonos",
147 | "language": "PHP",
148 | "author": {
149 | "name": "Craig Duncan",
150 | "link": "https://github.com/duncan3dc"
151 | },
152 | "usesGenerator": false
153 | },
154 | {
155 | "name": "gotwalt-ruby-sonos",
156 | "description": "Control Sonos speakers with Ruby.",
157 | "repository": "https://github.com/gotwalt/sonos",
158 | "language": "Ruby",
159 | "author": {
160 | "name": "Aaron Gotwalt",
161 | "link": "https://github.com/gotwalt"
162 | },
163 | "usesGenerator": false
164 | },
165 | {
166 | "name": "Liver64-php-sonos",
167 | "description": "GERMAN LANGUAGE: sonos2 ist eine Sammlung von Befehlen welche die php class PHPSonos nutzt um Sonos player via http Befehle von Loxone aus zu steuern.",
168 | "repository": "https://github.com/Liver64/PHP-Sonos-and-Loxone",
169 | "language": "PHP",
170 | "tags": ["loxone", "german"],
171 | "author": {
172 | "name": "Liver64",
173 | "link": "https://github.com/Liver64"
174 | },
175 | "usesGenerator": false
176 | },
177 | {
178 | "name": "Coollision-go-sonos",
179 | "description": "Golang package for controlling Sonoses",
180 | "link": "https://pkg.go.dev/github.com/Coollision/sonos#section-documentation",
181 | "repository": "https://github.com/Coollision/sonos",
182 | "language": "Go",
183 | "author": {
184 | "name": "Coollision",
185 | "link": "https://github.com/Coollision"
186 | },
187 | "usesGenerator": false
188 | },
189 | {
190 | "name": "ianr0bkny-go-sonos",
191 | "description": "A Go-language library for accessing UPnP AV devices",
192 | "repository": "https://github.com/ianr0bkny/go-sonos",
193 | "language": "Go",
194 | "author": {
195 | "name": "Ian T Richards",
196 | "link": "https://github.com/ianr0bkny"
197 | },
198 | "usesGenerator": false
199 | },
200 | {
201 | "name": "Sonos for IP-Symcon",
202 | "description": "IP-Symcon PHP Modul um Sonos Lautsprecher zu steuern",
203 | "repository": "https://github.com/tkugelberg/Sonos",
204 | "language": "PHP",
205 | "author": {
206 | "name": "Thorsten Kugelberg",
207 | "link": "https://github.com/tkugelberg"
208 | },
209 | "usesGenerator": false
210 | },
211 | {
212 | "name": "Sonos API in Java",
213 | "repository": "https://github.com/vmichalak/sonos-controller",
214 | "language":"Java",
215 | "author": {
216 | "name": "Valentin Michalak",
217 | "link": "https://github.com/vmichalak"
218 | },
219 | "usesGenerator": false
220 | },
221 | {
222 | "name": "Gonos",
223 | "description": "A Go module for controlling Sonos devices",
224 | "repository": "https://github.com/HandyGold75/Gonos",
225 | "language":"Go",
226 | "author": {
227 | "name": "HandyGold75",
228 | "link": "https://github.com/HandyGold75"
229 | },
230 | "usesGenerator": false
231 | }
232 | ]
233 | }
234 |
--------------------------------------------------------------------------------
/docs/_includes/apps.html:
--------------------------------------------------------------------------------
1 | Apps
2 | Open source apps talking to sonos speakers
3 |
4 |
5 | {% assign generated_apps = site.data.projects.apps | where:'usesGenerator', true | sort: 'name' %}
6 | {% assign other_apps = site.data.projects.apps | where:'usesGenerator', false | sort: 'name' %}
7 |
8 | {% for project in generated_apps %}
9 |
10 |
11 | {% include project-card.html %}
12 |
13 |
14 | {% endfor %}
15 |
16 | {% for project in other_apps %}
17 |
18 |
19 | {% include project-card.html %}
20 |
21 |
22 | {% endfor %}
23 |
24 |
--------------------------------------------------------------------------------
/docs/_includes/libraries.html:
--------------------------------------------------------------------------------
1 | Libraries
2 | Open source libraries for controlling sonos speakers
3 |
4 |
5 | {% assign generated_libraries = site.data.projects.libraries | where:'usesGenerator', true | sort: 'name' %}
6 | {% assign other_libraries = site.data.projects.libraries | where:'usesGenerator', false | sort: 'name' %}
7 |
8 | {% for project in generated_libraries %}
9 |
10 |
11 | {% include project-card.html %}
12 |
13 |
14 | {% endfor %}
15 |
16 | {% for project in other_libraries %}
17 |
18 |
19 | {% include project-card.html %}
20 |
21 |
22 | {% endfor %}
23 |
24 |
--------------------------------------------------------------------------------
/docs/_includes/project-card.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 | {% if project.usesGenerator %}{% octicon star-fill height:20 class:"mr-1 v-align-middle" fill:"#586069" aria-label:repo title:"This project uses the generator" %}{% endif %}
10 |
11 |
{{ project.description }}
12 |
{% for tag in project.tags %}{{tag}}{% if forloop.last == false %} {% endif %}{% endfor %}
13 |
14 |
32 |
33 |
--------------------------------------------------------------------------------
/docs/_sass/custom/custom.scss:
--------------------------------------------------------------------------------
1 | @import url("https://unpkg.com/primer/build/build.css");
2 | // .highlight{width:100%;overflow:auto;background:#ffffff}
3 | .highlight .c{color:#998;font-style:italic}
4 | // .highlight .err{color:#a61717;background-color:#e3d2d2}
5 | .highlight .k{font-weight:bold}
6 | .highlight .o{font-weight:bold}
7 | .highlight .cm{color:#999988;font-style:italic}
8 | .highlight .cp{color:#999999;font-weight:bold}
9 | .highlight .c1{color:#999988;font-style:italic}
10 | .highlight .cs{color:#999999;font-weight:bold;font-style:italic}
11 | .highlight .gd{color:#000000;background-color:#fdd}
12 | .highlight .gd .x{color:#000000;background-color:#faa}
13 | .highlight .ge{font-style:italic}
14 | .highlight .gr{color:#a00}
15 | .highlight .gh{color:#999}
16 | .highlight .gi{color:#000000;background-color:#dfd}
17 | .highlight .gi .x{color:#000000;background-color:#afa}
18 | .highlight .go{color:#888}
19 | .highlight .gp{color:#555}
20 | .highlight .gs{font-weight:bold}
21 | .highlight .gu{color:#aaa}
22 | .highlight .gt{color:#a00}
23 | .highlight .kc{font-weight:bold}
24 | .highlight .kd{font-weight:bold}
25 | .highlight .kp{font-weight:bold}
26 | .highlight .kr{font-weight:bold}
27 | .highlight .kt{color:#445588;font-weight:bold}
28 | .highlight .m{color:#099}
29 | .highlight .s{color:#d14}
30 | .highlight .na{color:teal}
31 | .highlight .nb{color:#0086B3}
32 | .highlight .nc{color:#445588;font-weight:bold}
33 | .highlight .no{color:teal}
34 | .highlight .ni{color:purple}
35 | .highlight .ne{color:#990000;font-weight:bold}
36 | .highlight .nf{color:#990000;font-weight:bold}
37 | .highlight .nn{color:#555}
38 | .highlight .nt{color:navy}
39 | .highlight .nv{color:teal}
40 | .highlight .ow{font-weight:bold}
41 | .highlight .w{color:#bbb}
42 | .highlight .mf{color:#099}
43 | .highlight .mh{color:#099}
44 | .highlight .mi{color:#099}
45 | .highlight .mo{color:#099}
46 | .highlight .sb{color:#d14}
47 | .highlight .sc{color:#d14}
48 | .highlight .sd{color:#d14}
49 | .highlight .s2{color:#d14}
50 | .highlight .se{color:#d14}
51 | .highlight .sh{color:#d14}
52 | .highlight .si{color:#d14}
53 | .highlight .sx{color:#d14}
54 | .highlight .sr{color:#009926}
55 | .highlight .s1{color:#d14}
56 | .highlight .ss{color:#990073}
57 | .highlight .bp{color:#999}
58 | .highlight .vc{color:teal}
59 | .highlight .vg{color:teal}
60 | .highlight .vi{color:teal}
61 | .highlight .il{color:#099}
62 | .highlight .lineno{-webkit-user-select:none;-moz-user-select:none;-o-user-select:none}
63 | .lineno::-moz-selection{background-color:transparent}
64 | .lineno::selection{background-color:transparent}
65 | .github-component{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol !important}
66 | .repo-language-color{filter:brightness(125%) !important;border-radius:50%;display:inline-block;height:12px;position:relative;top:2px;width:12px}
67 | .emoji{width:18px;height:auto;vertical-align:middle}
68 | .article h1,.article h2,.article h3,.article h4,.article .highlight{margin-bottom:16px}
69 | .article blockquote{color:#6a737d;border-left:2px solid #959da5;padding-left:16px;margin-bottom:16px}
70 | .article ul,.article ol{padding-left:32px;margin-bottom:16px}.article li ul,.article li ol{padding-left:16px;margin-bottom:0px}
71 | .min-height-full{min-height:100vh}
72 | .badge-primary{color:#fff;background-color:#007bff}
73 | .badge{display:inline-block;padding:.25em .6em;font-size:75%;font-weight:700;line-height:1;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:10rem}
74 | a.link-gray:hover { text-decoration: none;}
75 |
--------------------------------------------------------------------------------
/docs/developers.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | title: Developers
4 | nav_order: 21
5 | ---
6 |
7 | # Development of unofficial Sonos Documentation
8 |
9 | A lot of the files you see in this repository are generated with a custom build [generator](https://github.com/svrooij/sonos-api-docs/tree/main/generator/sonos-docs).
10 | This page describes how everything works together.
11 |
12 | ## Live preview on local machine
13 |
14 | We created a `docker-compose.yml` file so you can really easy see the resulting webpage on your local machine. Go to the `docs` folder and start the docker container that will compile the document source to a webpage on every save.
15 |
16 | ```bash
17 | cd ./docs
18 |
19 | # Run container (in foreground, will stop with CTRL+C)
20 | docker-compose up docs
21 | ```
22 |
23 | Once you have this running it will show some output about installing some ruby packages (inside the container, no worries). And then show the following message, this means the page is now available at `http://localhost:4000`:
24 |
25 | ```text
26 | docs_1 | Configuration file: /srv/jekyll/_config.yml
27 | docs_1 | Source: /srv/jekyll
28 | docs_1 | Destination: /srv/jekyll/_site
29 | docs_1 | Incremental build: enabled
30 | docs_1 | Generating...
31 | docs_1 | Remote Theme: Using theme svrooij/just-the-docs
32 | docs_1 | Jekyll Feed: Generating feed for posts
33 | docs_1 | GitHub Metadata: No GitHub API authentication could be found. Some fields may be missing or have incorrect data.
34 | docs_1 | done in 4.873 seconds.
35 | docs_1 | Auto-regeneration may not work on some Windows versions.
36 | docs_1 | Please see: https://github.com/Microsoft/BashOnWindows/issues/216
37 | docs_1 | If it does not work, please upgrade Bash on Windows or run Jekyll with --no-watch.
38 | docs_1 | Auto-regeneration: enabled for '/srv/jekyll'
39 | docs_1 | LiveReload address: http://0.0.0.0:35729
40 | docs_1 | Server address: http://0.0.0.0:4000//
41 | docs_1 | Server running... press ctrl-c to stop.
42 | docs_1 | LiveReload: Browser connected
43 | ```
44 |
45 | ## documentation.json
46 |
47 | The [documentation.json](https://github.com/svrooij/sonos-api-docs/blob/main/docs/documentation.json) file is where we could use some help. You don't need to know programming to describe all the actions sonos has.
48 |
49 | This file is used as one of the inputs for the generator.
50 | It allows us to set a nice description for each service and action. It also offers a way to describe each input/output parameter.
51 |
52 | For example [this part](https://github.com/svrooij/sonos-api-docs/blob/25aad3a3a25c029514669869705597df03c2b5d2/docs/documentation.json#L6-L37) is the source for the documentation you see on [this page]({{ '/services/alarm-clock.html' | relative_url }}).
53 |
54 | ## Custom generator
55 |
56 | We build a custom [generator](https://github.com/svrooij/sonos-api-docs/tree/main/generator/sonos-docs) to do several things.
57 |
58 | ### Discover services from Sonos speaker
59 |
60 | You can use the generator to generate [device discovery files]({{ '/#device-discovery-files' | relative_url }}). For each model we generated a discovery json, as available on main page. We generate this file by parsing the device discovery document available at `http://{sonos_ip}:1400/xml/device_description.xml`. Not every model has the same services, but it seems that if a service is available it's the same as all other models that have that service.
61 |
62 | (Re)generate discovery files:
63 |
64 | ```bash
65 | # Fork the repository
66 | # Clone to local folder
67 | # Go to folder
68 | cd /generator/sonos-docs
69 | # Install required packages
70 | npm install
71 | # on Windows
72 | .\bin\run services {sonos-ip}
73 | # on Unix/Mac
74 | ./bin/run services {sonos-ip}
75 | ```
76 |
77 | Please help us out occasionally by running this command on your own Sonos speaker and send us the resulting file. This way we can keep the discovery files up to date. This command will automatically update the discovery files in the `data` folder. These files are used as an input for the generator. Having up to date discovery files will help us to keep the documentation up to date. All personal identifiable information is removed from the discovery files.
78 |
79 | ### Combine discovery files and documentation
80 |
81 | If you changed the [documentation.json](./documentation.json) file or if you added/updated discovery files, you need to combine the two into one file, the **.cache/combined.json** file.
82 |
83 | This file is the result of the the manual documentation and the device discovery files. This file is almost 8000 lines of json at the moment, which is why it is ignored in git.
84 | Being able to inspect this json file should really help in debugging the generator.
85 |
86 | You can generate this file by running the following command:
87 |
88 | ```bash
89 | # Fork the repository
90 | # Clone to local folder
91 | # Go to folder
92 | cd /generator/sonos-docs
93 | # Install required packages
94 | npm install
95 | # on windows short for .\\bin\\run combine --docsFile=../../docs/documentation.json --folder=data
96 | npm run intermediate-win
97 | # on Unix/mac short for ./bin/run combine --docsFile=../../docs/documentation.json --folder=data
98 | npm run intermediate
99 |
100 | # or with npx from the root directory
101 | npx @svrooij/sonos-docs combine --docsFile=./docs/documentation.json --folder=./generator/sonos-docs/data --out=./generator/sonos-docs/.cache/combined.json
102 | ```
103 |
104 | ### Regenerate documentation
105 |
106 | Once you generated the **combined.json** file, you can use the generator to (re)generate the [service documentation]({{ '/services' | relative_url }}). This step is mandatory if you changed either the **documentation.json** or if you added/updated one of the discovery files.
107 |
108 | The resulting files, are **not to be changed manually**, since changes will get lost upon the next generation.
109 |
110 | | Template | Resulting file(s) |
111 | |-----------|------------------|
112 | | [services-index.hbs](https://github.com/svrooij/sonos-api-docs/blob/main/generator/sonos-docs/templates/docs/services-index.hbs)| [docs/services/index.md](https://github.com/svrooij/sonos-api-docs/blob/main/docs/services/index.md) |
113 | | [service.hbs](https://github.com/svrooij/sonos-api-docs/blob/main/generator/sonos-docs/templates/docs/service.hbs) | [docs/services/*.md](https://github.com/svrooij/sonos-api-docs/tree/main/docs/services) |
114 |
115 | Regenerate documentation:
116 |
117 | ```bash
118 | # Fork, clone, go to '/generator/sonos-docs' and run npm install
119 | # generate combined.json, see above
120 |
121 | # Regenerate documentation
122 | # on windows, short for .\\bin\\run generate docs ../../docs
123 | npm run docs-win
124 | # on unix/mac, short for ./bin/run generate docs ../../docs
125 | npm run docs
126 |
127 | # or with npx (from root folder)
128 | npx @svrooij/sonos-docs generate docs ./docs -i ./generator/sonos-docs/.cache/combined.json
129 | ```
130 |
131 | ### Use generator for other library
132 |
133 | The generator uses [Handlebars](https://handlebarsjs.com/) templates. A template is actually a folder with at least a [template.json](https://github.com/svrooij/sonos-api-docs/blob/main/generator/sonos-docs/templates/docs/template.json) file and one or more [template files](https://github.com/svrooij/sonos-api-docs/blob/main/generator/sonos-docs/templates/docs/services-index.hbs).
134 |
135 | The template.json file gives some basic information about the template, the author of that template and which files to use.
136 |
137 | 1. File usage `index`, will use the data from intermediate.json as input to produce **one file**.
138 | 2. File usage `service`, will use the data from each service to produce **one file per service**, be sure to use `{snService}` or `{service}` in the **outputFile**.
139 |
140 | Be sure to check out the [docs template](https://github.com/svrooij/sonos-api-docs/tree/main/generator/sonos-docs/templates/docs) to get started. Or the [ts template](https://github.com/svrooij/node-sonos-ts/tree/master/.generator/ts), which is used to generate [Sonos typescript](https://sonos-ts.svrooij.io/).
141 |
142 |
143 | ```bash
144 | # Fork, clone, go to '/generator/sonos-docs' and run npm install
145 | # generate combined.json, see above
146 |
147 | # generate library
148 | # [template-folder] can either be a folder relative to the current location, a full path to a template folder or the name of the folder inside the generator folder.
149 | # [root-output-folder] in what folder (relative or full path) should the resulting files be placed.
150 | # on windows
151 | .\bin\run generate [template-folder] [root-output-folder]
152 | # on unix/mac
153 | ./bin/run generate [template-folder] [root-output-folder]
154 |
155 | # or with npx
156 | npx @svrooij/sonos-docs generate [template-folder] [root-output-folder] -i ./generator/sonos-docs/.cache/combined.json
157 | ```
158 |
--------------------------------------------------------------------------------
/docs/docker-compose.yml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | version: "3.8"
4 | services:
5 | docs:
6 | image: jekyll/jekyll:3.8.5
7 | volumes:
8 | - "./:/srv/jekyll"
9 | ports:
10 | - "0.0.0.0:4000:4000"
11 | - "0.0.0.0:35729:35729"
12 | command: ["jekyll", "serve", "--livereload", "--watch", "--force_polling", "--incremental", "-b", "/"]
13 |
--------------------------------------------------------------------------------
/docs/index.md:
--------------------------------------------------------------------------------
1 | ---
2 | # Feel free to add content and custom Front Matter to this file.
3 | # To modify the layout, see https://jekyllrb.com/docs/themes/#overriding-theme-defaults
4 |
5 | layout: default
6 | title: Home
7 | nav_order: 1
8 | permalink: /
9 | ---
10 |
11 | # Unofficial Sonos Docs
12 |
13 | [![Sonos api documentation][badge_sonos-docs]][link_sonos-docs]
14 | [![Github Issues][badge_issues]][link_issues]
15 | [![Sonos2mqtt][badge_sonos-mqtt]][link_sonos-mqtt]
16 | [![Sonos cli][badge_sonos-cli]][link_sonos-cli]
17 | [![Sonos typescript this library][badge_sonos-typescript]][link_sonos-typescript]
18 |
19 | [![Support me on Github][badge_sponsor]][link_sponsor]
20 | [![Follow on Twitter][badge_twitter]][link_twitter]
21 |
22 | Sonos api documentation for the local UPNP api and a [generator](https://github.com/svrooij/sonos-api-docs/tree/main/generator/sonos-docs) to generate clients and documentation based on service discovery
23 |
24 | This library is in no way connected to [Sonos](//en.wikipedia.org/wiki/Sonos). It's just a set of text files to document a hidden and **unsupported** api.
25 |
26 | ## Documentation
27 |
28 | Check-out the (generated) documentation about all the [SONOS UPNP services]({{'services/' | relative_url }})
29 |
30 | ### Manually documented
31 |
32 | The [sonos services]({{'/services/' | relative_url }}) have no documentation, that is way we manually created a [documentation.json]({{ '/documentation.json' | relative_url }}) file. To easily add documentation to all services (that are generated with the generator). And it's json so you can easily use it yourself.
33 |
34 | - View/edit source [source documentation.json](https://github.com/svrooij/sonos-api-docs/blob/main/docs/documentation.json)
35 | - Download [documentation.json](http://sonos.svrooij.io/documentation.json)
36 |
37 | This file has a [documentation json schema](https://sonos.svrooij.io/schema/documentation.json) which means VS Code will guide you when editing this file.
38 |
39 | ### Update documentation
40 |
41 | If you change the [documentation](#manually-documented) file or if you did service discovery for a new device. You can update the documentation files with the following commands:
42 |
43 | ```shell
44 | # Go to generation folder
45 | cd generator/sonos-docs
46 |
47 | # Generate intermediate file
48 | npm run intermediate
49 | # or ./bin/run combine --docsFile=../../docs/documentation.json --folder=data
50 |
51 | # Generate documentation
52 | npm run docs
53 | # or ./bin/run generate docs ../../docs
54 | ```
55 |
56 | ## Generator
57 |
58 | You can find the generator [here](https://github.com/svrooij/sonos-api-docs/tree/main/generator/sonos-docs) and use it to generate your own Sonos client in your preferred language.
59 |
60 | ### Device discovery files
61 |
62 | You can use the generator to generate your own discovery files, but we also have the files available for download.
63 |
64 | | Player | Discovery file(s) |
65 | | ------ | ----------------- |
66 | | Sonos Play:1 | [S2](https://github.com/svrooij/sonos-api-docs/raw/main/generator/sonos-docs/data/sonos-S1-2.json) |
67 | | Sonos Play:3 | [S2](https://github.com/svrooij/sonos-api-docs/raw/main/generator/sonos-docs/data/sonos-S3-2.json) |
68 | | Sonos Play:5 (old) | [S1](https://github.com/svrooij/sonos-api-docs/raw/main/generator/sonos-docs/data/sonos-S5-1.json) |
69 | | Sonos Play:5 (new) | [S2](https://github.com/svrooij/sonos-api-docs/raw/main/generator/sonos-docs/data/sonos-S6-2.json) |
70 | | Sonos Playbar | [S2](https://github.com/svrooij/sonos-api-docs/raw/main/generator/sonos-docs/data/sonos-S9-2.json) |
71 | | Sonos One | [S2](https://github.com/svrooij/sonos-api-docs/raw/main/generator/sonos-docs/data/sonos-S13-2.json) |
72 | | Sonos Beam | [S2](https://github.com/svrooij/sonos-api-docs/raw/main/generator/sonos-docs/data/sonos-S14-2.json) |
73 | | Sonos Roam | [S2](https://github.com/svrooij/sonos-api-docs/raw/main/generator/sonos-docs/data/sonos-S27-2.json) |
74 | | Sonos Sub | [S2](https://github.com/svrooij/sonos-api-docs/raw/main/generator/sonos-docs/data/sonos-Sub-2.json) |
75 |
76 | These files toghether with the documentation file, are combined to a extensive JSON file, that is used as an input for the generator.
77 |
78 | ### Templates
79 |
80 | The generator uses [handlebars.js templates](https://handlebarsjs.com/) to generate the documentation/strong typed clients. Check-out the [docs template](https://github.com/svrooij/sonos-api-docs/tree/main/generator/sonos-docs/templates/docs) as a sample to develop your own templates.
81 |
82 | A template is a folder with a [template.json](https://github.com/svrooij/sonos-api-docs/tree/main/generator/sonos-docs/templates/docs/template.json) file, that describes the template and specifies what templates should be used to either generate an index (all services in a single file), or a seperate file for each service.
83 | The template.json also has a [json schema](https://svrooij.io/sonos-api-docs/schema/template.json) so VS Code will guide you when creating your own template.
84 |
85 | ## Community
86 |
87 | If you have any [questions](https://github.com/svrooij/sonos-api-docs/discussions/categories/q-a) or you want to [show](https://github.com/svrooij/sonos-api-docs/discussions/categories/show-and-tell) your Sonos integration. Please join us in the [discussions](https://github.com/svrooij/sonos-api-docs/discussions) tab on this repository.
88 |
89 | ## Contributors ✨
90 |
91 |
92 | [](#contributors-)
93 |
94 |
95 | Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)):
96 |
97 |
98 |
99 |
100 |
108 |
109 |
110 |
111 |
112 |
113 |
114 | This project follows the [all-contributors](https://github.com/all-contributors/all-contributors)
115 | specification. Contributions of any kind welcome!
116 |
117 | [badge_issues]: https://img.shields.io/github/issues/svrooij/sonos-api-docs?style=for-the-badge
118 | [badge_sonos-cli]: https://img.shields.io/badge/sonos-cli-blue?style=for-the-badge
119 | [badge_sonos-docs]: https://img.shields.io/badge/sonos-api-blue?style=for-the-badge
120 | [badge_sonos-mqtt]: https://img.shields.io/badge/sonos-mqtt-blue?style=for-the-badge
121 | [badge_sonos-typescript]: https://img.shields.io/badge/sonos-typescript-blue?style=for-the-badge
122 | [badge_sponsor]: https://img.shields.io/github/sponsors/svrooij?logo=github&style=for-the-badge
123 | [badge_twitter]: https://img.shields.io/twitter/follow/svrooij?logo=twitter&style=for-the-badge
124 |
125 | [link_sponsor]: https://github.com/sponsors/svrooij
126 | [link_issues]: https://github.com/svrooij/sonos-api-docs/issues
127 | [link_sonos-cli]: https://github.com/svrooij/sonos-cli
128 | [link_sonos-docs]: https://sonos.svrooij.io/
129 | [link_sonos-mqtt]: https://sonos2mqtt.svrooij.io/
130 | [link_sonos-typescript]: https://sonos-ts.svrooij.io/
131 | [link_twitter]: https://twitter.com/svrooij
132 |
--------------------------------------------------------------------------------
/docs/metadata.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | title: Metadata
4 | nav_order: 6
5 | ---
6 |
7 | ## Metadata explained
8 |
9 | A lot of requests to sonos require Metadata. This metadata is an xml describing the requested song.
10 |
11 | The metadata for an item can usually be fetched from a [remote music service](./music-services.md), but talking to those is hard.
12 |
13 | ## Known metadata
14 |
15 | Some metadata can be guessed based on common URLs.
16 |
17 | {% assign metadatas = site.data.metadata.metadata | sort: 'name' %}
18 | {% for meta in metadatas %}
19 |
20 | ### {{meta.name}}
21 |
22 | - Identifier: `{{meta.identifier}}`
23 | - Track URI: `{{meta.uri}}`
24 | {% if meta.sampleId %}- Sample ID: `{{meta.sampleId}}`{% endif %}
25 |
26 | ```xml
27 |
29 | -
30 | {{meta.metadata.class}}
31 | {{meta.metadata.didlDescription}}
32 | {% if meta.metadata.title %} {{meta.metadata.title}}
33 | {% endif -%}
34 |
35 |
36 | ```
37 |
38 | {% endfor %}
39 |
40 | ## Contribute
41 |
42 | This page is generated from [metadata.json](https://github.com/svrooij/sonos-api-docs/blob/main/docs/_data/metadata.json), which you can download [here](https://raw.githubusercontent.com/svrooij/sonos-api-docs/main/docs/_data/metadata.json).
43 |
--------------------------------------------------------------------------------
/docs/projects.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | title: Apps and libraries
4 | nav_order: 8
5 | ---
6 |
7 | {% include apps.html %}
8 |
9 | {% include libraries.html %}
10 |
11 | ### Auto generated
12 |
13 | This page is generated from [projects.json](https://github.com/svrooij/sonos-api-docs/blob/main/docs/_data/projects.json) if you want a project added to this list, send us a PR. Projects are ordered alphabetical, but projects that use the generator are displayed first.
14 |
15 | When you edit this file in VSCode, it's automatically checked for following the schema. You can also validate the **projects.json** from the command-line file before submitting your PR:
16 |
17 | ```shell
18 | npx ajv-cli -d ./docs/_data/projects.json -s ./docs/schema/projects.json -r ./docs/schema/author.json
19 | ```
20 |
--------------------------------------------------------------------------------
/docs/schema/author.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "http://json-schema.org/draft-07/schema#",
3 | "$id": "https://sonos.svrooij.io/schema/author.json",
4 | "title": "Author of specific item",
5 | "properties": {
6 | "link": {
7 | "type": "string"
8 | },
9 | "mail": {
10 | "type": "string"
11 | },
12 | "name": {
13 | "type": "string"
14 | }
15 | },
16 | "type": "object",
17 | "required": [
18 | "name"
19 | ]
20 | }
--------------------------------------------------------------------------------
/docs/schema/documentation.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "http://json-schema.org/draft-07/schema#",
3 | "$id": "https://sonos.svrooij.io/schema/documentation.json",
4 | "definitions": {
5 | "SonosServiceDocumentation": {
6 | "title": "Service name",
7 | "description": "The name of the service should match exactly to the name in the Service Discovery",
8 | "properties": {
9 | "actions": {
10 | "title": "Actions in this service",
11 | "additionalProperties": {
12 | "$ref": "#/definitions/SonosServiceDocumentationAction"
13 | },
14 | "type": "object"
15 | },
16 | "description": {
17 | "type": "string"
18 | },
19 | "errors": {
20 | "title": "Custom errors for this service",
21 | "type": "array",
22 | "items": {
23 | "$ref": "#/definitions/SonosCustomError"
24 | }
25 | },
26 | "variables": {
27 | "title": "Service variables",
28 | "type": "array",
29 | "items": {
30 | "$ref": "#/definitions/SonosServiceVariable"
31 | }
32 | }
33 | },
34 | "type": "object",
35 | "required": ["description"]
36 | },
37 | "SonosServiceDocumentationAction": {
38 | "title": "Action name",
39 | "description": "The name of the action should match exactly with the Service Discovery",
40 | "properties": {
41 | "description": {
42 | "title": "Short description of action",
43 | "type": "string"
44 | },
45 | "params": {
46 | "title": "Action parameters",
47 | "additionalProperties": {
48 | "title": "Parameter description",
49 | "description": "Describe a single input/output argument, by it name as key",
50 | "type": "string"
51 | },
52 | "type": "object"
53 | },
54 | "sample": {
55 | "title": "Sample values",
56 | "description": "Sample values for the parameters",
57 | "additionalProperties": {
58 | "title": "Value",
59 | "description": "Working value, by it name as key",
60 | "type": "string"
61 | },
62 | "type": "object"
63 | },
64 | "remarks": {
65 | "title": "Action remarks",
66 | "description": "Remarks about this action",
67 | "type": "string"
68 | }
69 | },
70 | "type": "object",
71 | "required": ["description"]
72 | },
73 | "SonosCustomError": {
74 | "title": "Custom error",
75 | "description": "Sonos defined custom errors per UPNP Service.",
76 | "properties": {
77 | "code": {
78 | "title": "Error code",
79 | "type": "number"
80 | },
81 | "description": {
82 | "title": "Error description",
83 | "type":"string"
84 | }
85 | },
86 | "default": {
87 | "code": 0,
88 | "description": ""
89 | },
90 | "type": "object",
91 | "required": ["code", "description"]
92 | },
93 | "SonosServiceVariable": {
94 | "title": "Service variable",
95 | "description": "Used for variable description and additional event properties",
96 | "type": "object",
97 | "properties": {
98 | "name": {
99 | "title": "Name of the event",
100 | "type": "string"
101 | },
102 | "dataType": {
103 | "type": "string",
104 | "enum": ["string", "boolean", "ui2", "i4", "ui4"]
105 | },
106 | "description": {
107 | "type":"string",
108 | "title": "Optional description"
109 | }
110 | },
111 | "required": ["name", "dataType"]
112 | }
113 | },
114 | "properties": {
115 | "license": {
116 | "title": "License of the current documentation, MIT is required to be included into the generator",
117 | "type": "string",
118 | "default": "MIT"
119 | },
120 | "language": {
121 | "type": "string",
122 | "title": "Language of the current documentation"
123 | },
124 | "services": {
125 | "title": "Each service is added with it's name as key",
126 | "additionalProperties": {
127 | "$ref": "#/definitions/SonosServiceDocumentation"
128 | },
129 | "type": "object"
130 | },
131 | "errors": {
132 | "title": "Default errors",
133 | "description": "These errors are used in all services.",
134 | "type": "array",
135 | "items": {
136 | "$ref": "#/definitions/SonosCustomError"
137 | }
138 | }
139 | },
140 | "type": "object",
141 | "required": ["license", "services", "language"]
142 | }
--------------------------------------------------------------------------------
/docs/schema/metadata.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "http://json-schema.org/draft-07/schema#",
3 | "$id": "https://sonos.svrooij.io/schema/metadata.json",
4 | "definitions": {
5 | "MetadataObject": {
6 | "default": {
7 | "service": -1,
8 | "name": "{ServiceName} {Kind}",
9 | "identifier": "service:track:{id}",
10 | "uri": "...{id}...",
11 | "metadata": {
12 | "id": "service:track:{id}",
13 | "class": "object.item.audioItem.musicTrack",
14 | "didlDescription": "SA_RINCON2311_X_#Svc2311-0-Token"
15 | }
16 | },
17 | "properties": {
18 | "service": {
19 | "title": "Service Identifier",
20 | "type": "integer",
21 | "default": -1
22 | },
23 | "name": {
24 | "type":"string",
25 | "title": "Metadata name",
26 | "description": "Name is used in documentation and logging",
27 | "default": "{ServiceName} {Kind}"
28 | },
29 | "identifier": {
30 | "title": "Item Identifier (lookup value)",
31 | "type": "string",
32 | "description": "Should include '{id}', which will be extracted",
33 | "default": "service:kind:{id}"
34 | },
35 | "uri": {
36 | "title": "Item URI",
37 | "description": "Full Item URI",
38 | "type":"string"
39 | },
40 | "sampleId": {
41 | "title": "Sample ID",
42 | "type":"string",
43 | "description": "Can be used to test this metadata"
44 | },
45 | "metadata": {
46 | "$ref": "#/definitions/Metadata"
47 | }
48 | },
49 | "type": "object",
50 | "required": [
51 | "service",
52 | "identifier",
53 | "uri",
54 | "name",
55 | "metadata"
56 | ]
57 | },
58 | "Metadata": {
59 | "properties": {
60 | "id": {
61 | "type": "string",
62 | "title": "Item ID"
63 | },
64 | "class": {
65 | "type": "string",
66 | "title": "UpnpClass"
67 | },
68 | "didlDescription": {
69 | "type":"string",
70 | "title": "DidlDescription",
71 | "description": "Service specific CdUdn, like 'SA_RINCON2311_X_#Svc2311-0-Token' for Spotify"
72 | },
73 | "title": {
74 | "type": "string",
75 | "title": "Item Title (not required)"
76 | },
77 | "parentId": {
78 | "type":"string",
79 | "title": "Parent ID (not required)"
80 | }
81 | },
82 | "type":"object",
83 | "required": [
84 | "id",
85 | "class",
86 | "didlDescription"
87 | ]
88 | }
89 | },
90 | "title": "Collection of lookup values for Sonos Speakers",
91 | "properties": {
92 | "metadata": {
93 | "items": {
94 | "$ref": "#/definitions/MetadataObject"
95 | },
96 | "type": "array",
97 | "minItems": 1
98 | }
99 | },
100 | "type": "object"
101 | }
102 |
--------------------------------------------------------------------------------
/docs/schema/projects.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "http://json-schema.org/draft-07/schema#",
3 | "$id": "https://sonos.svrooij.io/schema/projects.json",
4 | "definitions": {
5 | "Project": {
6 | "default": {
7 | "name": "",
8 | "repository": "",
9 | "usesGenerator": false
10 | },
11 | "properties": {
12 | "author": {
13 | "$ref": "author.json"
14 | },
15 | "name": {
16 | "title": "Project name",
17 | "type": "string"
18 | },
19 | "description": {
20 | "title": "Project description",
21 | "type": "string"
22 | },
23 | "language": {
24 | "title": "Used language",
25 | "description": "The language where this project is written in, or can be used with",
26 | "type":"string"
27 | },
28 | "link": {
29 | "title": "Link to project page",
30 | "type": "string"
31 | },
32 | "repository": {
33 | "title": "Link to repository page",
34 | "type": "string"
35 | },
36 | "tags": {
37 | "title": "Tags associated with this project",
38 | "type":"array"
39 | },
40 | "usesGenerator": {
41 | "title": "Project generated with provided generator?",
42 | "type":"boolean"
43 | }
44 | },
45 | "type": "object",
46 | "required": [
47 | "name",
48 | "usesGenerator"
49 | ],
50 | "anyOf": [
51 | { "required": ["link"]},
52 | { "required": ["repository"]}
53 | ]
54 | }
55 | },
56 | "title": "List of known projects using the local sonos api",
57 | "properties": {
58 | "apps": {
59 | "items": {
60 | "$ref": "#/definitions/Project"
61 | },
62 | "type": "array",
63 | "minItems": 1
64 | },
65 | "libraries": {
66 | "items": {
67 | "$ref": "#/definitions/Project"
68 | },
69 | "type": "array",
70 | "minItems": 1
71 | }
72 | },
73 | "type": "object"
74 | }
75 |
--------------------------------------------------------------------------------
/docs/schema/template.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "http://json-schema.org/draft-07/schema#",
3 | "$id": "https://sonos.svrooij.io/schema/template.json",
4 | "definitions": {
5 | "TemplateFile": {
6 | "properties": {
7 | "file": {
8 | "title": "Template filename",
9 | "type": "string"
10 | },
11 | "outputFile": {
12 | "title": "Output filename",
13 | "description": "How to output the file(s), '{service}' is replaced by the serviceName, '{snService}' is replaced by snakecase service name",
14 | "type": "string"
15 | },
16 | "usage": {
17 | "title": "Template use",
18 | "description": "Is this template used for all services combined of per service",
19 | "type": "string",
20 | "enum": [
21 | "index",
22 | "service"
23 | ]
24 | }
25 | },
26 | "required": [
27 | "file",
28 | "outputFile",
29 | "usage"
30 | ],
31 | "type": "object"
32 | }
33 | },
34 | "title": "Template configuration",
35 | "properties": {
36 | "author": {
37 | "$ref": "author.json"
38 | },
39 | "files": {
40 | "title": "Templates to process",
41 | "items": {
42 | "$ref": "#/definitions/TemplateFile"
43 | },
44 | "type": "array",
45 | "minItems": 1
46 | },
47 | "name": {
48 | "title": "Name of the template",
49 | "type": "string"
50 | },
51 | "slug": {
52 | "title": "Slug of the template",
53 | "description": "Slug has to be unique and match the tempalte folder, to be included into the generator",
54 | "type": "string"
55 | },
56 | "dataTypes": {
57 | "title": "Replace data types, original type as key, new type as value",
58 | "additionalProperties": {
59 | "type":"string"
60 | },
61 | "type":"object"
62 | },
63 | "serviceData": {
64 | "title": "Add data to each service, to use in your templates",
65 | "additionalProperties": {
66 | "title": "Use the exact service name as key",
67 | "type":"object"
68 | },
69 | "type":"object"
70 | },
71 | "license": {
72 | "title": "License of the template",
73 | "description": "'MIT' is required to be included into the generator",
74 | "default": "MIT",
75 | "type":"string"
76 | },
77 | "repository": {
78 | "title": "Code repositry",
79 | "description": "The repository where the resulting code is used",
80 | "type":"string"
81 | }
82 | },
83 | "required": [
84 | "author",
85 | "files",
86 | "slug"
87 | ],
88 | "type": "object"
89 | }
--------------------------------------------------------------------------------
/docs/services/audio-in.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | title: AudioIn
4 | parent: Sonos Services
5 | ---
6 | # AudioIn service
7 | {: .no_toc }
8 |
9 | Control line in
10 |
11 | The AudioIn service is available on these models: `Sonos Play:5 (S6) S2`.
12 |
13 | 1. TOC
14 | {:toc}
15 |
16 | ---
17 |
18 | ## Service data
19 | {: .no_toc }
20 |
21 | | name | value |
22 | |:-----|:------|
23 | | **Control URL** | `http://192.168.x.x:1400/AudioIn/Control` |
24 | | **Event subscription URL** | `http://192.168.x.x:1400/AudioIn/Event` |
25 | | **Discovery URL** | `http://192.168.x.x:1400/xml/AudioIn1.xml` |
26 | | **Service ID** | `urn:upnp-org:serviceId:AudioIn` |
27 | | **Service type** | `urn:schemas-upnp-org:service:AudioIn:1` |
28 |
29 | ### Sample request
30 | {: .no_toc }
31 |
32 | ```text
33 | POST /AudioIn/Control
34 | Host: 192.168.x.x:1400
35 | soapaction: "urn:schemas-upnp-org:service:AudioIn:1#{ActionName}"
36 | Content-Type: text/xml; charset="utf-8"
37 |
38 |
39 |
40 |
41 | {ActionBodyHere}
42 |
43 |
44 | ```
45 |
46 | ---
47 |
48 | ## Available actions
49 |
50 | ### GetAudioInputAttributes
51 |
52 | Action body:
53 |
54 | ```xml
55 |
56 |
57 | ```
58 |
59 | No input arguments
60 |
61 | Outputs:
62 |
63 | | parameter | type | description |
64 | |:----------|:-----|:------------|
65 | | **CurrentName** | `string` | |
66 | | **CurrentIcon** | `string` | |
67 |
68 | ### GetLineInLevel
69 |
70 | Action body:
71 |
72 | ```xml
73 |
74 |
75 | ```
76 |
77 | No input arguments
78 |
79 | Outputs:
80 |
81 | | parameter | type | description |
82 | |:----------|:-----|:------------|
83 | | **CurrentLeftLineInLevel** | `i4` | |
84 | | **CurrentRightLineInLevel** | `i4` | |
85 |
86 | ### SelectAudio
87 |
88 | Action body:
89 |
90 | ```xml
91 |
92 | string
93 |
94 | ```
95 |
96 | Inputs:
97 |
98 | | parameter | type | description |
99 | |:----------|:-----|:------------|
100 | | **ObjectID** | `string` | |
101 |
102 | ### SetAudioInputAttributes
103 |
104 | Action body:
105 |
106 | ```xml
107 |
108 | string
109 | string
110 |
111 | ```
112 |
113 | Inputs:
114 |
115 | | parameter | type | description |
116 | |:----------|:-----|:------------|
117 | | **DesiredName** | `string` | |
118 | | **DesiredIcon** | `string` | |
119 |
120 | ### SetLineInLevel
121 |
122 | Action body:
123 |
124 | ```xml
125 |
126 | i4
127 | i4
128 |
129 | ```
130 |
131 | Inputs:
132 |
133 | | parameter | type | description |
134 | |:----------|:-----|:------------|
135 | | **DesiredLeftLineInLevel** | `i4` | |
136 | | **DesiredRightLineInLevel** | `i4` | |
137 |
138 | ### StartTransmissionToGroup
139 |
140 | Action body:
141 |
142 | ```xml
143 |
144 | string
145 |
146 | ```
147 |
148 | Inputs:
149 |
150 | | parameter | type | description |
151 | |:----------|:-----|:------------|
152 | | **CoordinatorID** | `string` | |
153 |
154 | Outputs:
155 |
156 | | parameter | type | description |
157 | |:----------|:-----|:------------|
158 | | **CurrentTransportSettings** | `string` | |
159 |
160 | ### StopTransmissionToGroup
161 |
162 | Action body:
163 |
164 | ```xml
165 |
166 | string
167 |
168 | ```
169 |
170 | Inputs:
171 |
172 | | parameter | type | description |
173 | |:----------|:-----|:------------|
174 | | **CoordinatorID** | `string` | |
175 |
176 | ## Events
177 |
178 | The AudioInService has variables that might be emitted if you subscribe to events.
179 |
180 | ### Subscribe to events
181 |
182 | ```text
183 | SUBSCRIBE /AudioIn/Event
184 | Host: 192.168.x.x:1400
185 | callback:
186 | NT: upnp:event
187 | Timeout: Second-3600
188 | ```
189 |
190 | ### Event variables
191 |
192 | | Variable | Sends events* | type | possible values |
193 | |:---------|:-------------|:-----|:----------------|
194 | | AudioInputName | ✔ | `string` | |
195 | | Icon | ✔ | `string` | |
196 | | LeftLineInLevel | ✔ | `i4` | |
197 | | LineInConnected | ✔ | `boolean` | `1` for true and `0` for false |
198 | | Playing | ✔ | `boolean` | `1` for true and `0` for false |
199 | | RightLineInLevel | ✔ | `i4` | |
200 |
201 | If the variable has a `✔` in the Sends events column, the service discovery specifies this variable emits events. Other properties might be send as a part of `LastChange`
202 |
203 | ---
204 |
205 | This file is automatically generated with [@svrooij/sonos-docs](https://github.com/svrooij/sonos-api-docs/tree/main/generator/sonos-docs), do not edit manually.
206 |
207 | | Device | Software generation | Software version | Discovery date |
208 | |:-------|:--------------------|:-----------------|:---------------|
209 | | `Sonos Play:5 (S6)` | S2 | 64.3-19080 | 2021-08-18T06:06:35.970Z |
210 |
--------------------------------------------------------------------------------
/docs/services/connection-manager.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | title: ConnectionManager
4 | parent: Sonos Services
5 | ---
6 | # ConnectionManager service
7 | {: .no_toc }
8 |
9 | Services related to connections and protocols
10 |
11 | The ConnectionManager service is available on these models: `Sonos Play:1 (S1) S2` / `Sonos One (S13) S2` / `Sonos Beam (S14) S2` / `Sonos One (S18) S2` / `SYMFONISK Bookshelf (S21) S2` / `Sonos Roam (S27) S2` / `Sonos Play:3 (S3) S2` / `SYMFONISK Bookshelf (S33) S2` / `Sonos One SL (S38) S2` / `Sonos Play:5 (S6) S2` / `Sonos Playbar (S9) S2` / `Sonos Sub (Sub) S2`.
12 |
13 | 1. TOC
14 | {:toc}
15 |
16 | ---
17 |
18 | ## Service data
19 | {: .no_toc }
20 |
21 | | name | value |
22 | |:-----|:------|
23 | | **Control URL** | `http://192.168.x.x:1400/MediaRenderer/ConnectionManager/Control` |
24 | | **Event subscription URL** | `http://192.168.x.x:1400/MediaRenderer/ConnectionManager/Event` |
25 | | **Discovery URL** | `http://192.168.x.x:1400/xml/ConnectionManager1.xml` |
26 | | **Service ID** | `urn:upnp-org:serviceId:ConnectionManager` |
27 | | **Service type** | `urn:schemas-upnp-org:service:ConnectionManager:1` |
28 |
29 | ### Sample request
30 | {: .no_toc }
31 |
32 | ```text
33 | POST /MediaRenderer/ConnectionManager/Control
34 | Host: 192.168.x.x:1400
35 | soapaction: "urn:schemas-upnp-org:service:ConnectionManager:1#{ActionName}"
36 | Content-Type: text/xml; charset="utf-8"
37 |
38 |
39 |
40 |
41 | {ActionBodyHere}
42 |
43 |
44 | ```
45 |
46 | ---
47 |
48 | ## Available actions
49 |
50 | ### GetCurrentConnectionIDs
51 |
52 | Action body:
53 |
54 | ```xml
55 |
56 |
57 | ```
58 |
59 | No input arguments
60 |
61 | Outputs:
62 |
63 | | parameter | type | description |
64 | |:----------|:-----|:------------|
65 | | **ConnectionIDs** | `string` | |
66 |
67 | ### GetCurrentConnectionInfo
68 |
69 | Action body:
70 |
71 | ```xml
72 |
73 | i4
74 |
75 | ```
76 |
77 | Inputs:
78 |
79 | | parameter | type | description |
80 | |:----------|:-----|:------------|
81 | | **ConnectionID** | `i4` | |
82 |
83 | Outputs:
84 |
85 | | parameter | type | description |
86 | |:----------|:-----|:------------|
87 | | **RcsID** | `i4` | |
88 | | **AVTransportID** | `i4` | |
89 | | **ProtocolInfo** | `string` | |
90 | | **PeerConnectionManager** | `string` | |
91 | | **PeerConnectionID** | `i4` | |
92 | | **Direction** | `string` | Possible values: `Input` / `Output` |
93 | | **Status** | `string` | Possible values: `OK` / `ContentFormatMismatch` / `InsufficientBandwidth` / `UnreliableChannel` / `Unknown` |
94 |
95 | ### GetProtocolInfo
96 |
97 | Action body:
98 |
99 | ```xml
100 |
101 |
102 | ```
103 |
104 | No input arguments
105 |
106 | Outputs:
107 |
108 | | parameter | type | description |
109 | |:----------|:-----|:------------|
110 | | **Source** | `string` | |
111 | | **Sink** | `string` | |
112 |
113 | ## Events
114 |
115 | The ConnectionManagerService has variables that might be emitted if you subscribe to events.
116 |
117 | ### Subscribe to events
118 |
119 | ```text
120 | SUBSCRIBE /MediaRenderer/ConnectionManager/Event
121 | Host: 192.168.x.x:1400
122 | callback:
123 | NT: upnp:event
124 | Timeout: Second-3600
125 | ```
126 |
127 | ### Event variables
128 |
129 | | Variable | Sends events* | type | possible values |
130 | |:---------|:-------------|:-----|:----------------|
131 | | CurrentConnectionIDs | ✔ | `string` | |
132 | | SinkProtocolInfo | ✔ | `string` | |
133 | | SourceProtocolInfo | ✔ | `string` | |
134 |
135 | If the variable has a `✔` in the Sends events column, the service discovery specifies this variable emits events. Other properties might be send as a part of `LastChange`
136 |
137 | ---
138 |
139 | This file is automatically generated with [@svrooij/sonos-docs](https://github.com/svrooij/sonos-api-docs/tree/main/generator/sonos-docs), do not edit manually.
140 |
141 | | Device | Software generation | Software version | Discovery date |
142 | |:-------|:--------------------|:-----------------|:---------------|
143 | | `Sonos Play:1 (S1)` | S2 | 77.4-49290 | 2024-02-13T15:56:06.184Z |
144 | | `Sonos One (S13)` | S2 | 63.2-90210 | 2021-07-21T23:31:19.273Z |
145 | | `Sonos Beam (S14)` | S2 | 64.3-19080 | 2021-08-18T06:04:08.308Z |
146 | | `Sonos One (S18)` | S2 | 77.4-49290 | 2024-02-13T15:55:36.464Z |
147 | | `SYMFONISK Bookshelf (S21)` | S2 | 66.4-23300 | 2022-01-01T11:41:01.361Z |
148 | | `Sonos Roam (S27)` | S2 | 63.2-90210 | 2021-07-21T23:31:31.207Z |
149 | | `Sonos Play:3 (S3)` | S2 | 64.3-19080 | 2021-08-18T06:09:36.692Z |
150 | | `SYMFONISK Bookshelf (S33)` | S2 | 77.4-49290 | 2024-02-13T15:55:24.423Z |
151 | | `Sonos One SL (S38)` | S2 | 72.2-40060 | 2023-05-22T16:39:25.503Z |
152 | | `Sonos Play:5 (S6)` | S2 | 64.3-19080 | 2021-08-18T06:06:35.970Z |
153 | | `Sonos Playbar (S9)` | S2 | 77.4-49290 | 2024-02-13T15:55:46.307Z |
154 | | `Sonos Sub (Sub)` | S2 | 63.2-90210 | 2021-07-21T23:31:40.304Z |
155 |
--------------------------------------------------------------------------------
/docs/services/group-management.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | title: GroupManagement
4 | parent: Sonos Services
5 | ---
6 | # GroupManagement service
7 | {: .no_toc }
8 |
9 | Services related to groups
10 |
11 | The GroupManagement service is available on these models: `Sonos Play:1 (S1) S2` / `Sonos One (S13) S2` / `Sonos Beam (S14) S2` / `Sonos One (S18) S2` / `SYMFONISK Bookshelf (S21) S2` / `Sonos Roam (S27) S2` / `Sonos Play:3 (S3) S2` / `SYMFONISK Bookshelf (S33) S2` / `Sonos One SL (S38) S2` / `Sonos Play:5 (S6) S2` / `Sonos Playbar (S9) S2` / `Sonos Sub (Sub) S2`.
12 |
13 | 1. TOC
14 | {:toc}
15 |
16 | ---
17 |
18 | ## Service data
19 | {: .no_toc }
20 |
21 | | name | value |
22 | |:-----|:------|
23 | | **Control URL** | `http://192.168.x.x:1400/GroupManagement/Control` |
24 | | **Event subscription URL** | `http://192.168.x.x:1400/GroupManagement/Event` |
25 | | **Discovery URL** | `http://192.168.x.x:1400/xml/GroupManagement1.xml` |
26 | | **Service ID** | `urn:upnp-org:serviceId:GroupManagement` |
27 | | **Service type** | `urn:schemas-upnp-org:service:GroupManagement:1` |
28 |
29 | ### Sample request
30 | {: .no_toc }
31 |
32 | ```text
33 | POST /GroupManagement/Control
34 | Host: 192.168.x.x:1400
35 | soapaction: "urn:schemas-upnp-org:service:GroupManagement:1#{ActionName}"
36 | Content-Type: text/xml; charset="utf-8"
37 |
38 |
39 |
40 |
41 | {ActionBodyHere}
42 |
43 |
44 | ```
45 |
46 | ---
47 |
48 | ## Available actions
49 |
50 | ### AddMember
51 |
52 | Action body:
53 |
54 | ```xml
55 |
56 | string
57 | ui4
58 |
59 | ```
60 |
61 | Inputs:
62 |
63 | | parameter | type | description |
64 | |:----------|:-----|:------------|
65 | | **MemberID** | `string` | |
66 | | **BootSeq** | `ui4` | |
67 |
68 | Outputs:
69 |
70 | | parameter | type | description |
71 | |:----------|:-----|:------------|
72 | | **CurrentTransportSettings** | `string` | |
73 | | **CurrentURI** | `string` | |
74 | | **GroupUUIDJoined** | `string` | |
75 | | **ResetVolumeAfter** | `boolean` | `1` for true and `0` for false |
76 | | **VolumeAVTransportURI** | `string` | |
77 |
78 | ### RemoveMember
79 |
80 | Action body:
81 |
82 | ```xml
83 |
84 | string
85 |
86 | ```
87 |
88 | Inputs:
89 |
90 | | parameter | type | description |
91 | |:----------|:-----|:------------|
92 | | **MemberID** | `string` | |
93 |
94 | ### ReportTrackBufferingResult
95 |
96 | Action body:
97 |
98 | ```xml
99 |
100 | string
101 | i4
102 |
103 | ```
104 |
105 | Inputs:
106 |
107 | | parameter | type | description |
108 | |:----------|:-----|:------------|
109 | | **MemberID** | `string` | |
110 | | **ResultCode** | `i4` | |
111 |
112 | ### SetSourceAreaIds
113 |
114 | Action body:
115 |
116 | ```xml
117 |
118 | string
119 |
120 | ```
121 |
122 | Inputs:
123 |
124 | | parameter | type | description |
125 | |:----------|:-----|:------------|
126 | | **DesiredSourceAreaIds** | `string` | |
127 |
128 | ## Events
129 |
130 | The GroupManagementService has variables that might be emitted if you subscribe to events.
131 |
132 | ### Subscribe to events
133 |
134 | ```text
135 | SUBSCRIBE /GroupManagement/Event
136 | Host: 192.168.x.x:1400
137 | callback:
138 | NT: upnp:event
139 | Timeout: Second-3600
140 | ```
141 |
142 | ### Event variables
143 |
144 | | Variable | Sends events* | type | possible values |
145 | |:---------|:-------------|:-----|:----------------|
146 | | GroupCoordinatorIsLocal | ✔ | `boolean` | `1` for true and `0` for false |
147 | | LocalGroupUUID | ✔ | `string` | |
148 | | ResetVolumeAfter | ✔ | `boolean` | `1` for true and `0` for false |
149 | | SourceAreaIds | | `string` | |
150 | | VirtualLineInGroupID | ✔ | `string` | |
151 | | VolumeAVTransportURI | ✔ | `string` | |
152 |
153 | If the variable has a `✔` in the Sends events column, the service discovery specifies this variable emits events. Other properties might be send as a part of `LastChange`
154 |
155 | ---
156 |
157 | This file is automatically generated with [@svrooij/sonos-docs](https://github.com/svrooij/sonos-api-docs/tree/main/generator/sonos-docs), do not edit manually.
158 |
159 | | Device | Software generation | Software version | Discovery date |
160 | |:-------|:--------------------|:-----------------|:---------------|
161 | | `Sonos Play:1 (S1)` | S2 | 77.4-49290 | 2024-02-13T15:56:06.184Z |
162 | | `Sonos One (S13)` | S2 | 63.2-90210 | 2021-07-21T23:31:19.273Z |
163 | | `Sonos Beam (S14)` | S2 | 64.3-19080 | 2021-08-18T06:04:08.308Z |
164 | | `Sonos One (S18)` | S2 | 77.4-49290 | 2024-02-13T15:55:36.464Z |
165 | | `SYMFONISK Bookshelf (S21)` | S2 | 66.4-23300 | 2022-01-01T11:41:01.361Z |
166 | | `Sonos Roam (S27)` | S2 | 63.2-90210 | 2021-07-21T23:31:31.207Z |
167 | | `Sonos Play:3 (S3)` | S2 | 64.3-19080 | 2021-08-18T06:09:36.692Z |
168 | | `SYMFONISK Bookshelf (S33)` | S2 | 77.4-49290 | 2024-02-13T15:55:24.423Z |
169 | | `Sonos One SL (S38)` | S2 | 72.2-40060 | 2023-05-22T16:39:25.503Z |
170 | | `Sonos Play:5 (S6)` | S2 | 64.3-19080 | 2021-08-18T06:06:35.970Z |
171 | | `Sonos Playbar (S9)` | S2 | 77.4-49290 | 2024-02-13T15:55:46.307Z |
172 | | `Sonos Sub (Sub)` | S2 | 63.2-90210 | 2021-07-21T23:31:40.304Z |
173 |
--------------------------------------------------------------------------------
/docs/services/group-rendering-control.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | title: GroupRenderingControl
4 | parent: Sonos Services
5 | ---
6 | # GroupRenderingControl service
7 | {: .no_toc }
8 |
9 | Volume related controls for groups
10 |
11 | The GroupRenderingControl service is available on these models: `Sonos Play:1 (S1) S2` / `Sonos One (S13) S2` / `Sonos Beam (S14) S2` / `Sonos One (S18) S2` / `SYMFONISK Bookshelf (S21) S2` / `Sonos Roam (S27) S2` / `Sonos Play:3 (S3) S2` / `SYMFONISK Bookshelf (S33) S2` / `Sonos One SL (S38) S2` / `Sonos Play:5 (S6) S2` / `Sonos Playbar (S9) S2` / `Sonos Sub (Sub) S2`.
12 |
13 | 1. TOC
14 | {:toc}
15 |
16 | ---
17 |
18 | ## Service data
19 | {: .no_toc }
20 |
21 | | name | value |
22 | |:-----|:------|
23 | | **Control URL** | `http://192.168.x.x:1400/MediaRenderer/GroupRenderingControl/Control` |
24 | | **Event subscription URL** | `http://192.168.x.x:1400/MediaRenderer/GroupRenderingControl/Event` |
25 | | **Discovery URL** | `http://192.168.x.x:1400/xml/GroupRenderingControl1.xml` |
26 | | **Service ID** | `urn:upnp-org:serviceId:GroupRenderingControl` |
27 | | **Service type** | `urn:schemas-upnp-org:service:GroupRenderingControl:1` |
28 |
29 | ### Sample request
30 | {: .no_toc }
31 |
32 | ```text
33 | POST /MediaRenderer/GroupRenderingControl/Control
34 | Host: 192.168.x.x:1400
35 | soapaction: "urn:schemas-upnp-org:service:GroupRenderingControl:1#{ActionName}"
36 | Content-Type: text/xml; charset="utf-8"
37 |
38 |
39 |
40 |
41 | {ActionBodyHere}
42 |
43 |
44 | ```
45 |
46 | ---
47 |
48 | ## Available actions
49 |
50 | ### GetGroupMute
51 |
52 | Get the group mute state.
53 |
54 | Action body:
55 |
56 | ```xml
57 |
58 | ui4
59 |
60 | ```
61 |
62 | Inputs:
63 |
64 | | parameter | type | description |
65 | |:----------|:-----|:------------|
66 | | **InstanceID** | `ui4` | InstanceID should always be `0` |
67 |
68 | Outputs:
69 |
70 | | parameter | type | description |
71 | |:----------|:-----|:------------|
72 | | **CurrentMute** | `boolean` | `1` for true and `0` for false |
73 |
74 | **Remarks** Should be send to coordinator only
75 |
76 | ### GetGroupVolume
77 |
78 | Get the group volume.
79 |
80 | Action body:
81 |
82 | ```xml
83 |
84 | ui4
85 |
86 | ```
87 |
88 | Inputs:
89 |
90 | | parameter | type | description |
91 | |:----------|:-----|:------------|
92 | | **InstanceID** | `ui4` | InstanceID should always be `0` |
93 |
94 | Outputs:
95 |
96 | | parameter | type | description |
97 | |:----------|:-----|:------------|
98 | | **CurrentVolume** | `ui2` | |
99 |
100 | **Remarks** Should be send to coordinator only
101 |
102 | ### SetGroupMute
103 |
104 | (Un-/)Mute the entire group
105 |
106 | Action body:
107 |
108 | ```xml
109 |
110 | ui4
111 | boolean
112 |
113 | ```
114 |
115 | Inputs:
116 |
117 | | parameter | type | description |
118 | |:----------|:-----|:------------|
119 | | **InstanceID** | `ui4` | InstanceID should always be `0` |
120 | | **DesiredMute** | `boolean` | Allowed values: `1` (= true) / `0` (= false) |
121 |
122 | **Remarks** Should be send to coordinator only
123 |
124 | ### SetGroupVolume
125 |
126 | Change group volume. Players volume will be changed proportionally based on last snapshot
127 |
128 | Action body:
129 |
130 | ```xml
131 |
132 | ui4
133 | ui2
134 |
135 | ```
136 |
137 | Inputs:
138 |
139 | | parameter | type | description |
140 | |:----------|:-----|:------------|
141 | | **InstanceID** | `ui4` | InstanceID should always be `0` |
142 | | **DesiredVolume** | `ui2` | New volume between 0 and 100 |
143 |
144 | **Remarks** Should be send to coordinator only
145 |
146 | ### SetRelativeGroupVolume
147 |
148 | Relatively change group volume - returns final group volume. Players volume will be changed proportionally based on last snapshot
149 |
150 | Action body:
151 |
152 | ```xml
153 |
154 | ui4
155 | i4
156 |
157 | ```
158 |
159 | Inputs:
160 |
161 | | parameter | type | description |
162 | |:----------|:-----|:------------|
163 | | **InstanceID** | `ui4` | InstanceID should always be `0` |
164 | | **Adjustment** | `i4` | Number between -100 and +100 |
165 |
166 | Outputs:
167 |
168 | | parameter | type | description |
169 | |:----------|:-----|:------------|
170 | | **NewVolume** | `ui2` | |
171 |
172 | **Remarks** Should be send to coordinator only
173 |
174 | ### SnapshotGroupVolume
175 |
176 | Creates a new group volume snapshot, the volume ratio between all players. It is used by SetGroupVolume and SetRelativeGroupVolume
177 |
178 | Action body:
179 |
180 | ```xml
181 |
182 | ui4
183 |
184 | ```
185 |
186 | Inputs:
187 |
188 | | parameter | type | description |
189 | |:----------|:-----|:------------|
190 | | **InstanceID** | `ui4` | InstanceID should always be `0` |
191 |
192 | **Remarks** Should be send to coordinator only
193 |
194 | ## Events
195 |
196 | The GroupRenderingControlService has variables that might be emitted if you subscribe to events.
197 |
198 | ### Subscribe to events
199 |
200 | ```text
201 | SUBSCRIBE /MediaRenderer/GroupRenderingControl/Event
202 | Host: 192.168.x.x:1400
203 | callback:
204 | NT: upnp:event
205 | Timeout: Second-3600
206 | ```
207 |
208 | ### Event variables
209 |
210 | | Variable | Sends events* | type | possible values |
211 | |:---------|:-------------|:-----|:----------------|
212 | | GroupMute | ✔ | `boolean` | `1` for true and `0` for false |
213 | | GroupVolume | ✔ | `ui2` | |
214 | | GroupVolumeChangeable | ✔ | `boolean` | `1` for true and `0` for false |
215 |
216 | If the variable has a `✔` in the Sends events column, the service discovery specifies this variable emits events. Other properties might be send as a part of `LastChange`
217 |
218 | ## Custom errors
219 |
220 | The GroupRenderingControlService has the following known custom errors.
221 |
222 | | Error code | Description |
223 | |:-----------|:------------|
224 | | `701` | Player isn't the coordinator |
225 |
226 | ---
227 |
228 | This file is automatically generated with [@svrooij/sonos-docs](https://github.com/svrooij/sonos-api-docs/tree/main/generator/sonos-docs), do not edit manually.
229 |
230 | | Device | Software generation | Software version | Discovery date |
231 | |:-------|:--------------------|:-----------------|:---------------|
232 | | `Sonos Play:1 (S1)` | S2 | 77.4-49290 | 2024-02-13T15:56:06.184Z |
233 | | `Sonos One (S13)` | S2 | 63.2-90210 | 2021-07-21T23:31:19.273Z |
234 | | `Sonos Beam (S14)` | S2 | 64.3-19080 | 2021-08-18T06:04:08.308Z |
235 | | `Sonos One (S18)` | S2 | 77.4-49290 | 2024-02-13T15:55:36.464Z |
236 | | `SYMFONISK Bookshelf (S21)` | S2 | 66.4-23300 | 2022-01-01T11:41:01.361Z |
237 | | `Sonos Roam (S27)` | S2 | 63.2-90210 | 2021-07-21T23:31:31.207Z |
238 | | `Sonos Play:3 (S3)` | S2 | 64.3-19080 | 2021-08-18T06:09:36.692Z |
239 | | `SYMFONISK Bookshelf (S33)` | S2 | 77.4-49290 | 2024-02-13T15:55:24.423Z |
240 | | `Sonos One SL (S38)` | S2 | 72.2-40060 | 2023-05-22T16:39:25.503Z |
241 | | `Sonos Play:5 (S6)` | S2 | 64.3-19080 | 2021-08-18T06:06:35.970Z |
242 | | `Sonos Playbar (S9)` | S2 | 77.4-49290 | 2024-02-13T15:55:46.307Z |
243 | | `Sonos Sub (Sub)` | S2 | 63.2-90210 | 2021-07-21T23:31:40.304Z |
244 |
--------------------------------------------------------------------------------
/docs/services/ht-control.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | title: HTControl
4 | parent: Sonos Services
5 | ---
6 | # HTControl service
7 | {: .no_toc }
8 |
9 | Service related to the TV remote control
10 |
11 | The HTControl service is available on these models: `Sonos Beam (S14) S2` / `Sonos Playbar (S9) S2`.
12 |
13 | 1. TOC
14 | {:toc}
15 |
16 | ---
17 |
18 | ## Service data
19 | {: .no_toc }
20 |
21 | | name | value |
22 | |:-----|:------|
23 | | **Control URL** | `http://192.168.x.x:1400/HTControl/Control` |
24 | | **Event subscription URL** | `http://192.168.x.x:1400/HTControl/Event` |
25 | | **Discovery URL** | `http://192.168.x.x:1400/xml/HTControl1.xml` |
26 | | **Service ID** | `urn:upnp-org:serviceId:HTControl` |
27 | | **Service type** | `urn:schemas-upnp-org:service:HTControl:1` |
28 |
29 | ### Sample request
30 | {: .no_toc }
31 |
32 | ```text
33 | POST /HTControl/Control
34 | Host: 192.168.x.x:1400
35 | soapaction: "urn:schemas-upnp-org:service:HTControl:1#{ActionName}"
36 | Content-Type: text/xml; charset="utf-8"
37 |
38 |
39 |
40 |
41 | {ActionBodyHere}
42 |
43 |
44 | ```
45 |
46 | ---
47 |
48 | ## Available actions
49 |
50 | ### CommitLearnedIRCodes
51 |
52 | Action body:
53 |
54 | ```xml
55 |
56 | string
57 |
58 | ```
59 |
60 | Inputs:
61 |
62 | | parameter | type | description |
63 | |:----------|:-----|:------------|
64 | | **Name** | `string` | |
65 |
66 | ### GetIRRepeaterState
67 |
68 | Action body:
69 |
70 | ```xml
71 |
72 |
73 | ```
74 |
75 | No input arguments
76 |
77 | Outputs:
78 |
79 | | parameter | type | description |
80 | |:----------|:-----|:------------|
81 | | **CurrentIRRepeaterState** | `string` | Possible values: `On` / `Off` / `Disabled` |
82 |
83 | ### GetLEDFeedbackState
84 |
85 | Action body:
86 |
87 | ```xml
88 |
89 |
90 | ```
91 |
92 | No input arguments
93 |
94 | Outputs:
95 |
96 | | parameter | type | description |
97 | |:----------|:-----|:------------|
98 | | **LEDFeedbackState** | `string` | Possible values: `On` / `Off` |
99 |
100 | ### IdentifyIRRemote
101 |
102 | Action body:
103 |
104 | ```xml
105 |
106 | ui4
107 |
108 | ```
109 |
110 | Inputs:
111 |
112 | | parameter | type | description |
113 | |:----------|:-----|:------------|
114 | | **Timeout** | `ui4` | |
115 |
116 | ### IsRemoteConfigured
117 |
118 | Action body:
119 |
120 | ```xml
121 |
122 |
123 | ```
124 |
125 | No input arguments
126 |
127 | Outputs:
128 |
129 | | parameter | type | description |
130 | |:----------|:-----|:------------|
131 | | **RemoteConfigured** | `boolean` | `1` for true and `0` for false |
132 |
133 | ### LearnIRCode
134 |
135 | Action body:
136 |
137 | ```xml
138 |
139 | string
140 | ui4
141 |
142 | ```
143 |
144 | Inputs:
145 |
146 | | parameter | type | description |
147 | |:----------|:-----|:------------|
148 | | **IRCode** | `string` | |
149 | | **Timeout** | `ui4` | |
150 |
151 | ### SetIRRepeaterState
152 |
153 | Action body:
154 |
155 | ```xml
156 |
157 | string
158 |
159 | ```
160 |
161 | Inputs:
162 |
163 | | parameter | type | description |
164 | |:----------|:-----|:------------|
165 | | **DesiredIRRepeaterState** | `string` | Allowed values: `On` / `Off` / `Disabled` |
166 |
167 | ### SetLEDFeedbackState
168 |
169 | Action body:
170 |
171 | ```xml
172 |
173 | string
174 |
175 | ```
176 |
177 | Inputs:
178 |
179 | | parameter | type | description |
180 | |:----------|:-----|:------------|
181 | | **LEDFeedbackState** | `string` | Allowed values: `On` / `Off` |
182 |
183 | ## Events
184 |
185 | The HTControlService has variables that might be emitted if you subscribe to events.
186 |
187 | ### Subscribe to events
188 |
189 | ```text
190 | SUBSCRIBE /HTControl/Event
191 | Host: 192.168.x.x:1400
192 | callback:
193 | NT: upnp:event
194 | Timeout: Second-3600
195 | ```
196 |
197 | ### Event variables
198 |
199 | | Variable | Sends events* | type | possible values |
200 | |:---------|:-------------|:-----|:----------------|
201 | | IRRepeaterState | ✔ | `string` | `On` / `Off` / `Disabled` |
202 | | LEDFeedbackState | | `string` | `On` / `Off` |
203 | | RemoteConfigured | | `boolean` | `1` for true and `0` for false |
204 | | TOSLinkConnected | ✔ | `boolean` | `1` for true and `0` for false |
205 |
206 | If the variable has a `✔` in the Sends events column, the service discovery specifies this variable emits events. Other properties might be send as a part of `LastChange`
207 |
208 | ---
209 |
210 | This file is automatically generated with [@svrooij/sonos-docs](https://github.com/svrooij/sonos-api-docs/tree/main/generator/sonos-docs), do not edit manually.
211 |
212 | | Device | Software generation | Software version | Discovery date |
213 | |:-------|:--------------------|:-----------------|:---------------|
214 | | `Sonos Beam (S14)` | S2 | 64.3-19080 | 2021-08-18T06:04:08.308Z |
215 | | `Sonos Playbar (S9)` | S2 | 77.4-49290 | 2024-02-13T15:55:46.307Z |
216 |
--------------------------------------------------------------------------------
/docs/services/index.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | title: Sonos Services
4 | has_children: true
5 | nav_order: 5
6 | has_toc: false
7 | ---
8 |
9 | # Sonos SOAP Services
10 | {: .no_toc }
11 |
12 | Every sonos speaker has several soap services. Each service has one or more actions you can call.
13 |
14 | ## UPNP specifications
15 |
16 | Sonos speaker follow the [MediaServer:4 and MediaRenderer:3 specifications](https://openconnectivity.org/developer/specifications/upnp-resources/upnp/mediaserver4-and-mediarenderer3/) by the [Open Connectivity Foundation](https://openconnectivity.org/).
17 | These documents can provide you with some extra guidelines. More details can be found at [Sonos communication]({{'/sonos-communication.html' | relative_url }}), which show you how to exactly do a call to the sonos speakers.
18 |
19 | ## All available services
20 | {: .no_toc }
21 |
22 | | Service | Description |
23 | |:--------|:------------|
24 | | [**AlarmClock**](alarm-clock.html) | Control the sonos alarms and times |
25 | | [**AudioIn**](audio-in.html) | Control line in |
26 | | [**AVTransport**](av-transport.html) | Service that controls stuff related to transport (play/pause/next/special URLs) |
27 | | [**ConnectionManager**](connection-manager.html) | Services related to connections and protocols |
28 | | [**ContentDirectory**](content-directory.html) | Browse for local content |
29 | | [**DeviceProperties**](device-properties.html) | Modify device properties, like LED status and stereo pairs |
30 | | [**GroupManagement**](group-management.html) | Services related to groups |
31 | | [**GroupRenderingControl**](group-rendering-control.html) | Volume related controls for groups |
32 | | [**HTControl**](ht-control.html) | Service related to the TV remote control |
33 | | [**MusicServices**](music-services.html) | Access to external music services, like Spotify or Youtube Music |
34 | | [**QPlay**](q-play.html) | Services related to Chinese Tencent Qplay service |
35 | | [**Queue**](queue.html) | Modify and browse queues |
36 | | [**RenderingControl**](rendering-control.html) | Volume related controls |
37 | | [**SystemProperties**](system-properties.html) | Manage system-wide settings, mainly account stuff |
38 | | [**VirtualLineIn**](virtual-line-in.html) | |
39 | | [**ZoneGroupTopology**](zone-group-topology.html) | Zone config stuff, eg getting all the configured sonos zones |
40 |
41 | ## UPNP errors
42 |
43 | These are the default UPNP errors.
44 |
45 | | Error code | Description |
46 | |:-----------|:------------|
47 | | `400` | Bad request |
48 | | `401` | Invalid action |
49 | | `402` | Invalid args |
50 | | `404` | Invalid var |
51 | | `412` | Precondition failed |
52 | | `501` | Action failed |
53 | | `600` | Argument value invalid |
54 | | `601` | Argument value out of range |
55 | | `602` | Optional action not implemented |
56 | | `603` | Out of memory |
57 | | `604` | Human intervention required |
58 | | `605` | String argument too long |
59 | | `606` | Action not authorized |
60 | | `607` | Signature failure |
61 | | `608` | Signature missing |
62 | | `609` | Not encrypted |
63 | | `610` | Invalid sequence |
64 | | `611` | Invalid control URL |
65 | | `612` | No such session |
66 |
67 | ---
68 |
69 | This file is automatically generated with [@svrooij/sonos-docs](https://github.com/svrooij/sonos-api-docs/tree/main/generator/sonos-docs), do not edit manually.
70 |
71 | | Device | Software generation | Software version | Discovery date |
72 | |:-------|:--------------------|:-----------------|:---------------|
73 | | `Sonos Play:1 (S1)` | S2 | 77.4-49290 | 2024-02-13T15:56:06.184Z |
74 | | `Sonos One (S13)` | S2 | 63.2-90210 | 2021-07-21T23:31:19.273Z |
75 | | `Sonos Beam (S14)` | S2 | 64.3-19080 | 2021-08-18T06:04:08.308Z |
76 | | `Sonos One (S18)` | S2 | 77.4-49290 | 2024-02-13T15:55:36.464Z |
77 | | `SYMFONISK Bookshelf (S21)` | S2 | 66.4-23300 | 2022-01-01T11:41:01.361Z |
78 | | `Sonos Roam (S27)` | S2 | 63.2-90210 | 2021-07-21T23:31:31.207Z |
79 | | `Sonos Play:3 (S3)` | S2 | 64.3-19080 | 2021-08-18T06:09:36.692Z |
80 | | `SYMFONISK Bookshelf (S33)` | S2 | 77.4-49290 | 2024-02-13T15:55:24.423Z |
81 | | `Sonos One SL (S38)` | S2 | 72.2-40060 | 2023-05-22T16:39:25.503Z |
82 | | `Sonos Play:5 (S6)` | S2 | 64.3-19080 | 2021-08-18T06:06:35.970Z |
83 | | `Sonos Playbar (S9)` | S2 | 77.4-49290 | 2024-02-13T15:55:46.307Z |
84 | | `Sonos Sub (Sub)` | S2 | 63.2-90210 | 2021-07-21T23:31:40.304Z |
85 |
--------------------------------------------------------------------------------
/docs/services/music-services.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | title: MusicServices
4 | parent: Sonos Services
5 | ---
6 | # MusicServices service
7 | {: .no_toc }
8 |
9 | Access to external music services, like Spotify or Youtube Music
10 |
11 | The MusicServices service is available on these models: `Sonos Play:1 (S1) S2` / `Sonos One (S13) S2` / `Sonos Beam (S14) S2` / `Sonos One (S18) S2` / `SYMFONISK Bookshelf (S21) S2` / `Sonos Roam (S27) S2` / `Sonos Play:3 (S3) S2` / `SYMFONISK Bookshelf (S33) S2` / `Sonos One SL (S38) S2` / `Sonos Play:5 (S6) S2` / `Sonos Playbar (S9) S2` / `Sonos Sub (Sub) S2`.
12 |
13 | 1. TOC
14 | {:toc}
15 |
16 | ---
17 |
18 | ## Service data
19 | {: .no_toc }
20 |
21 | | name | value |
22 | |:-----|:------|
23 | | **Control URL** | `http://192.168.x.x:1400/MusicServices/Control` |
24 | | **Event subscription URL** | `http://192.168.x.x:1400/MusicServices/Event` |
25 | | **Discovery URL** | `http://192.168.x.x:1400/xml/MusicServices1.xml` |
26 | | **Service ID** | `urn:upnp-org:serviceId:MusicServices` |
27 | | **Service type** | `urn:schemas-upnp-org:service:MusicServices:1` |
28 |
29 | ### Sample request
30 | {: .no_toc }
31 |
32 | ```text
33 | POST /MusicServices/Control
34 | Host: 192.168.x.x:1400
35 | soapaction: "urn:schemas-upnp-org:service:MusicServices:1#{ActionName}"
36 | Content-Type: text/xml; charset="utf-8"
37 |
38 |
39 |
40 |
41 | {ActionBodyHere}
42 |
43 |
44 | ```
45 |
46 | ---
47 |
48 | ## Available actions
49 |
50 | ### GetSessionId
51 |
52 | Action body:
53 |
54 | ```xml
55 |
56 | ui4
57 | string
58 |
59 | ```
60 |
61 | Inputs:
62 |
63 | | parameter | type | description |
64 | |:----------|:-----|:------------|
65 | | **ServiceId** | `ui4` | |
66 | | **Username** | `string` | |
67 |
68 | Outputs:
69 |
70 | | parameter | type | description |
71 | |:----------|:-----|:------------|
72 | | **SessionId** | `string` | |
73 |
74 | ### ListAvailableServices
75 |
76 | Load music service list as xml
77 |
78 | Action body:
79 |
80 | ```xml
81 |
82 |
83 | ```
84 |
85 | No input arguments
86 |
87 | Outputs:
88 |
89 | | parameter | type | description |
90 | |:----------|:-----|:------------|
91 | | **AvailableServiceDescriptorList** | `string` | |
92 | | **AvailableServiceTypeList** | `string` | |
93 | | **AvailableServiceListVersion** | `string` | |
94 |
95 | **Remarks** Some libraries also support ListAndParseAvailableServices
96 |
97 | ### UpdateAvailableServices
98 |
99 | Action body:
100 |
101 | ```xml
102 |
103 |
104 | ```
105 |
106 | No input arguments
107 |
108 | ## Events
109 |
110 | The MusicServicesService has variables that might be emitted if you subscribe to events.
111 |
112 | ### Subscribe to events
113 |
114 | ```text
115 | SUBSCRIBE /MusicServices/Event
116 | Host: 192.168.x.x:1400
117 | callback:
118 | NT: upnp:event
119 | Timeout: Second-3600
120 | ```
121 |
122 | ### Event variables
123 |
124 | | Variable | Sends events* | type | possible values |
125 | |:---------|:-------------|:-----|:----------------|
126 | | ServiceId | | `ui4` | |
127 | | ServiceListVersion | ✔ | `string` | |
128 | | SessionId | | `string` | |
129 | | Username | | `string` | |
130 |
131 | If the variable has a `✔` in the Sends events column, the service discovery specifies this variable emits events. Other properties might be send as a part of `LastChange`
132 |
133 | ---
134 |
135 | This file is automatically generated with [@svrooij/sonos-docs](https://github.com/svrooij/sonos-api-docs/tree/main/generator/sonos-docs), do not edit manually.
136 |
137 | | Device | Software generation | Software version | Discovery date |
138 | |:-------|:--------------------|:-----------------|:---------------|
139 | | `Sonos Play:1 (S1)` | S2 | 77.4-49290 | 2024-02-13T15:56:06.184Z |
140 | | `Sonos One (S13)` | S2 | 63.2-90210 | 2021-07-21T23:31:19.273Z |
141 | | `Sonos Beam (S14)` | S2 | 64.3-19080 | 2021-08-18T06:04:08.308Z |
142 | | `Sonos One (S18)` | S2 | 77.4-49290 | 2024-02-13T15:55:36.464Z |
143 | | `SYMFONISK Bookshelf (S21)` | S2 | 66.4-23300 | 2022-01-01T11:41:01.361Z |
144 | | `Sonos Roam (S27)` | S2 | 63.2-90210 | 2021-07-21T23:31:31.207Z |
145 | | `Sonos Play:3 (S3)` | S2 | 64.3-19080 | 2021-08-18T06:09:36.692Z |
146 | | `SYMFONISK Bookshelf (S33)` | S2 | 77.4-49290 | 2024-02-13T15:55:24.423Z |
147 | | `Sonos One SL (S38)` | S2 | 72.2-40060 | 2023-05-22T16:39:25.503Z |
148 | | `Sonos Play:5 (S6)` | S2 | 64.3-19080 | 2021-08-18T06:06:35.970Z |
149 | | `Sonos Playbar (S9)` | S2 | 77.4-49290 | 2024-02-13T15:55:46.307Z |
150 | | `Sonos Sub (Sub)` | S2 | 63.2-90210 | 2021-07-21T23:31:40.304Z |
151 |
--------------------------------------------------------------------------------
/docs/services/q-play.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | title: QPlay
4 | parent: Sonos Services
5 | ---
6 | # QPlay service
7 | {: .no_toc }
8 |
9 | Services related to Chinese Tencent Qplay service
10 |
11 | The QPlay service is available on these models: `Sonos Play:1 (S1) S2` / `Sonos One (S13) S2` / `Sonos Beam (S14) S2` / `Sonos One (S18) S2` / `SYMFONISK Bookshelf (S21) S2` / `Sonos Roam (S27) S2` / `Sonos Play:3 (S3) S2` / `SYMFONISK Bookshelf (S33) S2` / `Sonos One SL (S38) S2` / `Sonos Play:5 (S6) S2` / `Sonos Playbar (S9) S2` / `Sonos Sub (Sub) S2`.
12 |
13 | 1. TOC
14 | {:toc}
15 |
16 | ---
17 |
18 | ## Service data
19 | {: .no_toc }
20 |
21 | | name | value |
22 | |:-----|:------|
23 | | **Control URL** | `http://192.168.x.x:1400/QPlay/Control` |
24 | | **Event subscription URL** | `http://192.168.x.x:1400/QPlay/Event` |
25 | | **Discovery URL** | `http://192.168.x.x:1400/xml/QPlay1.xml` |
26 | | **Service ID** | `urn:tencent-com:serviceId:QPlay` |
27 | | **Service type** | `urn:schemas-tencent-com:service:QPlay:1` |
28 |
29 | ### Sample request
30 | {: .no_toc }
31 |
32 | ```text
33 | POST /QPlay/Control
34 | Host: 192.168.x.x:1400
35 | soapaction: "urn:schemas-tencent-com:service:QPlay:1#{ActionName}"
36 | Content-Type: text/xml; charset="utf-8"
37 |
38 |
39 |
40 |
41 | {ActionBodyHere}
42 |
43 |
44 | ```
45 |
46 | ---
47 |
48 | ## Available actions
49 |
50 | ### QPlayAuth
51 |
52 | Action body:
53 |
54 | ```xml
55 |
56 | string
57 |
58 | ```
59 |
60 | Inputs:
61 |
62 | | parameter | type | description |
63 | |:----------|:-----|:------------|
64 | | **Seed** | `string` | |
65 |
66 | Outputs:
67 |
68 | | parameter | type | description |
69 | |:----------|:-----|:------------|
70 | | **Code** | `string` | |
71 | | **MID** | `string` | |
72 | | **DID** | `string` | |
73 |
74 |
75 | ---
76 |
77 | This file is automatically generated with [@svrooij/sonos-docs](https://github.com/svrooij/sonos-api-docs/tree/main/generator/sonos-docs), do not edit manually.
78 |
79 | | Device | Software generation | Software version | Discovery date |
80 | |:-------|:--------------------|:-----------------|:---------------|
81 | | `Sonos Play:1 (S1)` | S2 | 77.4-49290 | 2024-02-13T15:56:06.184Z |
82 | | `Sonos One (S13)` | S2 | 63.2-90210 | 2021-07-21T23:31:19.273Z |
83 | | `Sonos Beam (S14)` | S2 | 64.3-19080 | 2021-08-18T06:04:08.308Z |
84 | | `Sonos One (S18)` | S2 | 77.4-49290 | 2024-02-13T15:55:36.464Z |
85 | | `SYMFONISK Bookshelf (S21)` | S2 | 66.4-23300 | 2022-01-01T11:41:01.361Z |
86 | | `Sonos Roam (S27)` | S2 | 63.2-90210 | 2021-07-21T23:31:31.207Z |
87 | | `Sonos Play:3 (S3)` | S2 | 64.3-19080 | 2021-08-18T06:09:36.692Z |
88 | | `SYMFONISK Bookshelf (S33)` | S2 | 77.4-49290 | 2024-02-13T15:55:24.423Z |
89 | | `Sonos One SL (S38)` | S2 | 72.2-40060 | 2023-05-22T16:39:25.503Z |
90 | | `Sonos Play:5 (S6)` | S2 | 64.3-19080 | 2021-08-18T06:06:35.970Z |
91 | | `Sonos Playbar (S9)` | S2 | 77.4-49290 | 2024-02-13T15:55:46.307Z |
92 | | `Sonos Sub (Sub)` | S2 | 63.2-90210 | 2021-07-21T23:31:40.304Z |
93 |
--------------------------------------------------------------------------------
/docs/services/queue.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | title: Queue
4 | parent: Sonos Services
5 | ---
6 | # Queue service
7 | {: .no_toc }
8 |
9 | Modify and browse queues
10 |
11 | The Queue service is available on these models: `Sonos Play:1 (S1) S2` / `Sonos One (S13) S2` / `Sonos Beam (S14) S2` / `Sonos One (S18) S2` / `SYMFONISK Bookshelf (S21) S2` / `Sonos Roam (S27) S2` / `Sonos Play:3 (S3) S2` / `SYMFONISK Bookshelf (S33) S2` / `Sonos One SL (S38) S2` / `Sonos Play:5 (S6) S2` / `Sonos Playbar (S9) S2` / `Sonos Sub (Sub) S2`.
12 |
13 | 1. TOC
14 | {:toc}
15 |
16 | ---
17 |
18 | ## Service data
19 | {: .no_toc }
20 |
21 | | name | value |
22 | |:-----|:------|
23 | | **Control URL** | `http://192.168.x.x:1400/MediaRenderer/Queue/Control` |
24 | | **Event subscription URL** | `http://192.168.x.x:1400/MediaRenderer/Queue/Event` |
25 | | **Discovery URL** | `http://192.168.x.x:1400/xml/Queue1.xml` |
26 | | **Service ID** | `urn:sonos-com:serviceId:Queue` |
27 | | **Service type** | `urn:schemas-sonos-com:service:Queue:1` |
28 |
29 | ### Sample request
30 | {: .no_toc }
31 |
32 | ```text
33 | POST /MediaRenderer/Queue/Control
34 | Host: 192.168.x.x:1400
35 | soapaction: "urn:schemas-sonos-com:service:Queue:1#{ActionName}"
36 | Content-Type: text/xml; charset="utf-8"
37 |
38 |
39 |
40 |
41 | {ActionBodyHere}
42 |
43 |
44 | ```
45 |
46 | ---
47 |
48 | ## Available actions
49 |
50 | ### AddMultipleURIs
51 |
52 | Action body:
53 |
54 | ```xml
55 |
56 | ui4
57 | ui4
58 | string
59 | string
60 | ui4
61 | boolean
62 | ui4
63 | string
64 |
65 | ```
66 |
67 | Inputs:
68 |
69 | | parameter | type | description |
70 | |:----------|:-----|:------------|
71 | | **QueueID** | `ui4` | |
72 | | **UpdateID** | `ui4` | |
73 | | **ContainerURI** | `string` | |
74 | | **ContainerMetaData** | `string` | Embedded XML |
75 | | **DesiredFirstTrackNumberEnqueued** | `ui4` | |
76 | | **EnqueueAsNext** | `boolean` | Allowed values: `1` (= true) / `0` (= false) |
77 | | **NumberOfURIs** | `ui4` | |
78 | | **EnqueuedURIsAndMetaData** | `string` | Embedded XML |
79 |
80 | Outputs:
81 |
82 | | parameter | type | description |
83 | |:----------|:-----|:------------|
84 | | **FirstTrackNumberEnqueued** | `ui4` | |
85 | | **NumTracksAdded** | `ui4` | |
86 | | **NewQueueLength** | `ui4` | |
87 | | **NewUpdateID** | `ui4` | |
88 |
89 | ### AddURI
90 |
91 | Action body:
92 |
93 | ```xml
94 |
95 | ui4
96 | ui4
97 | string
98 | string
99 | ui4
100 | boolean
101 |
102 | ```
103 |
104 | Inputs:
105 |
106 | | parameter | type | description |
107 | |:----------|:-----|:------------|
108 | | **QueueID** | `ui4` | |
109 | | **UpdateID** | `ui4` | |
110 | | **EnqueuedURI** | `string` | |
111 | | **EnqueuedURIMetaData** | `string` | Embedded XML |
112 | | **DesiredFirstTrackNumberEnqueued** | `ui4` | |
113 | | **EnqueueAsNext** | `boolean` | Allowed values: `1` (= true) / `0` (= false) |
114 |
115 | Outputs:
116 |
117 | | parameter | type | description |
118 | |:----------|:-----|:------------|
119 | | **FirstTrackNumberEnqueued** | `ui4` | |
120 | | **NumTracksAdded** | `ui4` | |
121 | | **NewQueueLength** | `ui4` | |
122 | | **NewUpdateID** | `ui4` | |
123 |
124 | ### AttachQueue
125 |
126 | Action body:
127 |
128 | ```xml
129 |
130 | string
131 |
132 | ```
133 |
134 | Inputs:
135 |
136 | | parameter | type | description |
137 | |:----------|:-----|:------------|
138 | | **QueueOwnerID** | `string` | |
139 |
140 | Outputs:
141 |
142 | | parameter | type | description |
143 | |:----------|:-----|:------------|
144 | | **QueueID** | `ui4` | |
145 | | **QueueOwnerContext** | `string` | |
146 |
147 | ### Backup
148 |
149 | Action body:
150 |
151 | ```xml
152 |
153 |
154 | ```
155 |
156 | No input arguments
157 |
158 | ### Browse
159 |
160 | Action body:
161 |
162 | ```xml
163 |
164 | ui4
165 | ui4
166 | ui4
167 |
168 | ```
169 |
170 | Inputs:
171 |
172 | | parameter | type | description |
173 | |:----------|:-----|:------------|
174 | | **QueueID** | `ui4` | |
175 | | **StartingIndex** | `ui4` | |
176 | | **RequestedCount** | `ui4` | |
177 |
178 | Outputs:
179 |
180 | | parameter | type | description |
181 | |:----------|:-----|:------------|
182 | | **Result** | `string` | |
183 | | **NumberReturned** | `ui4` | |
184 | | **TotalMatches** | `ui4` | |
185 | | **UpdateID** | `ui4` | |
186 |
187 | ### CreateQueue
188 |
189 | Action body:
190 |
191 | ```xml
192 |
193 | string
194 | string
195 | string
196 |
197 | ```
198 |
199 | Inputs:
200 |
201 | | parameter | type | description |
202 | |:----------|:-----|:------------|
203 | | **QueueOwnerID** | `string` | |
204 | | **QueueOwnerContext** | `string` | |
205 | | **QueuePolicy** | `string` | |
206 |
207 | Outputs:
208 |
209 | | parameter | type | description |
210 | |:----------|:-----|:------------|
211 | | **QueueID** | `ui4` | |
212 |
213 | ### RemoveAllTracks
214 |
215 | Action body:
216 |
217 | ```xml
218 |
219 | ui4
220 | ui4
221 |
222 | ```
223 |
224 | Inputs:
225 |
226 | | parameter | type | description |
227 | |:----------|:-----|:------------|
228 | | **QueueID** | `ui4` | |
229 | | **UpdateID** | `ui4` | |
230 |
231 | Outputs:
232 |
233 | | parameter | type | description |
234 | |:----------|:-----|:------------|
235 | | **NewUpdateID** | `ui4` | |
236 |
237 | ### RemoveTrackRange
238 |
239 | Action body:
240 |
241 | ```xml
242 |
243 | ui4
244 | ui4
245 | ui4
246 | ui4
247 |
248 | ```
249 |
250 | Inputs:
251 |
252 | | parameter | type | description |
253 | |:----------|:-----|:------------|
254 | | **QueueID** | `ui4` | |
255 | | **UpdateID** | `ui4` | |
256 | | **StartingIndex** | `ui4` | |
257 | | **NumberOfTracks** | `ui4` | |
258 |
259 | Outputs:
260 |
261 | | parameter | type | description |
262 | |:----------|:-----|:------------|
263 | | **NewUpdateID** | `ui4` | |
264 |
265 | ### ReorderTracks
266 |
267 | Action body:
268 |
269 | ```xml
270 |
271 | ui4
272 | ui4
273 | ui4
274 | ui4
275 | ui4
276 |
277 | ```
278 |
279 | Inputs:
280 |
281 | | parameter | type | description |
282 | |:----------|:-----|:------------|
283 | | **QueueID** | `ui4` | |
284 | | **StartingIndex** | `ui4` | |
285 | | **NumberOfTracks** | `ui4` | |
286 | | **InsertBefore** | `ui4` | |
287 | | **UpdateID** | `ui4` | |
288 |
289 | Outputs:
290 |
291 | | parameter | type | description |
292 | |:----------|:-----|:------------|
293 | | **NewUpdateID** | `ui4` | |
294 |
295 | ### ReplaceAllTracks
296 |
297 | Action body:
298 |
299 | ```xml
300 |
301 | ui4
302 | ui4
303 | string
304 | string
305 | ui4
306 | string
307 | ui4
308 | string
309 |
310 | ```
311 |
312 | Inputs:
313 |
314 | | parameter | type | description |
315 | |:----------|:-----|:------------|
316 | | **QueueID** | `ui4` | |
317 | | **UpdateID** | `ui4` | |
318 | | **ContainerURI** | `string` | |
319 | | **ContainerMetaData** | `string` | Embedded XML |
320 | | **CurrentTrackIndex** | `ui4` | |
321 | | **NewCurrentTrackIndices** | `string` | |
322 | | **NumberOfURIs** | `ui4` | |
323 | | **EnqueuedURIsAndMetaData** | `string` | Embedded XML |
324 |
325 | Outputs:
326 |
327 | | parameter | type | description |
328 | |:----------|:-----|:------------|
329 | | **NewQueueLength** | `ui4` | |
330 | | **NewUpdateID** | `ui4` | |
331 |
332 | ### SaveAsSonosPlaylist
333 |
334 | Action body:
335 |
336 | ```xml
337 |
338 | ui4
339 | string
340 | string
341 |
342 | ```
343 |
344 | Inputs:
345 |
346 | | parameter | type | description |
347 | |:----------|:-----|:------------|
348 | | **QueueID** | `ui4` | |
349 | | **Title** | `string` | |
350 | | **ObjectID** | `string` | |
351 |
352 | Outputs:
353 |
354 | | parameter | type | description |
355 | |:----------|:-----|:------------|
356 | | **AssignedObjectID** | `string` | |
357 |
358 | ## Events
359 |
360 | The QueueService has variables that might be emitted if you subscribe to events.
361 |
362 | ### Subscribe to events
363 |
364 | ```text
365 | SUBSCRIBE /MediaRenderer/Queue/Event
366 | Host: 192.168.x.x:1400
367 | callback:
368 | NT: upnp:event
369 | Timeout: Second-3600
370 | ```
371 |
372 | ### Event variables
373 |
374 | | Variable | Sends events* | type | possible values |
375 | |:---------|:-------------|:-----|:----------------|
376 | | Curated | | `boolean` | `1` for true and `0` for false |
377 | | LastChange | ✔ | `string` | |
378 | | UpdateID | | `ui4` | |
379 |
380 | If the variable has a `✔` in the Sends events column, the service discovery specifies this variable emits events. Other properties might be send as a part of `LastChange`
381 |
382 | ---
383 |
384 | This file is automatically generated with [@svrooij/sonos-docs](https://github.com/svrooij/sonos-api-docs/tree/main/generator/sonos-docs), do not edit manually.
385 |
386 | | Device | Software generation | Software version | Discovery date |
387 | |:-------|:--------------------|:-----------------|:---------------|
388 | | `Sonos Play:1 (S1)` | S2 | 77.4-49290 | 2024-02-13T15:56:06.184Z |
389 | | `Sonos One (S13)` | S2 | 63.2-90210 | 2021-07-21T23:31:19.273Z |
390 | | `Sonos Beam (S14)` | S2 | 64.3-19080 | 2021-08-18T06:04:08.308Z |
391 | | `Sonos One (S18)` | S2 | 77.4-49290 | 2024-02-13T15:55:36.464Z |
392 | | `SYMFONISK Bookshelf (S21)` | S2 | 66.4-23300 | 2022-01-01T11:41:01.361Z |
393 | | `Sonos Roam (S27)` | S2 | 63.2-90210 | 2021-07-21T23:31:31.207Z |
394 | | `Sonos Play:3 (S3)` | S2 | 64.3-19080 | 2021-08-18T06:09:36.692Z |
395 | | `SYMFONISK Bookshelf (S33)` | S2 | 77.4-49290 | 2024-02-13T15:55:24.423Z |
396 | | `Sonos One SL (S38)` | S2 | 72.2-40060 | 2023-05-22T16:39:25.503Z |
397 | | `Sonos Play:5 (S6)` | S2 | 64.3-19080 | 2021-08-18T06:06:35.970Z |
398 | | `Sonos Playbar (S9)` | S2 | 77.4-49290 | 2024-02-13T15:55:46.307Z |
399 | | `Sonos Sub (Sub)` | S2 | 63.2-90210 | 2021-07-21T23:31:40.304Z |
400 |
--------------------------------------------------------------------------------
/docs/services/virtual-line-in.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | title: VirtualLineIn
4 | parent: Sonos Services
5 | ---
6 | # VirtualLineIn service
7 | {: .no_toc }
8 |
9 | The VirtualLineIn service is available on these models: `Sonos Play:1 (S1) S2` / `Sonos One (S13) S2` / `Sonos Beam (S14) S2` / `Sonos One (S18) S2` / `SYMFONISK Bookshelf (S21) S2` / `Sonos Roam (S27) S2` / `Sonos Play:3 (S3) S2` / `SYMFONISK Bookshelf (S33) S2` / `Sonos One SL (S38) S2` / `Sonos Play:5 (S6) S2` / `Sonos Playbar (S9) S2` / `Sonos Sub (Sub) S2`.
10 |
11 | 1. TOC
12 | {:toc}
13 |
14 | ---
15 |
16 | ## Service data
17 | {: .no_toc }
18 |
19 | | name | value |
20 | |:-----|:------|
21 | | **Control URL** | `http://192.168.x.x:1400/MediaRenderer/VirtualLineIn/Control` |
22 | | **Event subscription URL** | `http://192.168.x.x:1400/MediaRenderer/VirtualLineIn/Event` |
23 | | **Discovery URL** | `http://192.168.x.x:1400/xml/VirtualLineIn1.xml` |
24 | | **Service ID** | `urn:upnp-org:serviceId:VirtualLineIn` |
25 | | **Service type** | `urn:schemas-upnp-org:service:VirtualLineIn:1` |
26 |
27 | ### Sample request
28 | {: .no_toc }
29 |
30 | ```text
31 | POST /MediaRenderer/VirtualLineIn/Control
32 | Host: 192.168.x.x:1400
33 | soapaction: "urn:schemas-upnp-org:service:VirtualLineIn:1#{ActionName}"
34 | Content-Type: text/xml; charset="utf-8"
35 |
36 |
37 |
38 |
39 | {ActionBodyHere}
40 |
41 |
42 | ```
43 |
44 | ---
45 |
46 | ## Available actions
47 |
48 | ### Next
49 |
50 | Action body:
51 |
52 | ```xml
53 |
54 | ui4
55 |
56 | ```
57 |
58 | Inputs:
59 |
60 | | parameter | type | description |
61 | |:----------|:-----|:------------|
62 | | **InstanceID** | `ui4` | |
63 |
64 | ### Pause
65 |
66 | Action body:
67 |
68 | ```xml
69 |
70 | ui4
71 |
72 | ```
73 |
74 | Inputs:
75 |
76 | | parameter | type | description |
77 | |:----------|:-----|:------------|
78 | | **InstanceID** | `ui4` | |
79 |
80 | ### Play
81 |
82 | Action body:
83 |
84 | ```xml
85 |
86 | ui4
87 | string
88 |
89 | ```
90 |
91 | Inputs:
92 |
93 | | parameter | type | description |
94 | |:----------|:-----|:------------|
95 | | **InstanceID** | `ui4` | |
96 | | **Speed** | `string` | |
97 |
98 | ### Previous
99 |
100 | Action body:
101 |
102 | ```xml
103 |
104 | ui4
105 |
106 | ```
107 |
108 | Inputs:
109 |
110 | | parameter | type | description |
111 | |:----------|:-----|:------------|
112 | | **InstanceID** | `ui4` | |
113 |
114 | ### SetVolume
115 |
116 | Action body:
117 |
118 | ```xml
119 |
120 | ui4
121 | ui2
122 |
123 | ```
124 |
125 | Inputs:
126 |
127 | | parameter | type | description |
128 | |:----------|:-----|:------------|
129 | | **InstanceID** | `ui4` | |
130 | | **DesiredVolume** | `ui2` | |
131 |
132 | ### StartTransmission
133 |
134 | Action body:
135 |
136 | ```xml
137 |
138 | ui4
139 | string
140 |
141 | ```
142 |
143 | Inputs:
144 |
145 | | parameter | type | description |
146 | |:----------|:-----|:------------|
147 | | **InstanceID** | `ui4` | |
148 | | **CoordinatorID** | `string` | |
149 |
150 | Outputs:
151 |
152 | | parameter | type | description |
153 | |:----------|:-----|:------------|
154 | | **CurrentTransportSettings** | `string` | |
155 |
156 | ### Stop
157 |
158 | Action body:
159 |
160 | ```xml
161 |
162 | ui4
163 |
164 | ```
165 |
166 | Inputs:
167 |
168 | | parameter | type | description |
169 | |:----------|:-----|:------------|
170 | | **InstanceID** | `ui4` | |
171 |
172 | ### StopTransmission
173 |
174 | Action body:
175 |
176 | ```xml
177 |
178 | ui4
179 | string
180 |
181 | ```
182 |
183 | Inputs:
184 |
185 | | parameter | type | description |
186 | |:----------|:-----|:------------|
187 | | **InstanceID** | `ui4` | |
188 | | **CoordinatorID** | `string` | |
189 |
190 | ## Events
191 |
192 | The VirtualLineInService has variables that might be emitted if you subscribe to events.
193 |
194 | ### Subscribe to events
195 |
196 | ```text
197 | SUBSCRIBE /MediaRenderer/VirtualLineIn/Event
198 | Host: 192.168.x.x:1400
199 | callback:
200 | NT: upnp:event
201 | Timeout: Second-3600
202 | ```
203 |
204 | ### Event variables
205 |
206 | | Variable | Sends events* | type | possible values |
207 | |:---------|:-------------|:-----|:----------------|
208 | | AVTransportURIMetaData | | `string` | Embedded XML |
209 | | CurrentTrackMetaData | ✔ | `string` | Embedded XML |
210 | | CurrentTransportActions | | `string` | |
211 | | EnqueuedTransportURIMetaData | | `string` | Embedded XML |
212 | | LastChange | ✔ | `string` | |
213 |
214 | If the variable has a `✔` in the Sends events column, the service discovery specifies this variable emits events. Other properties might be send as a part of `LastChange`
215 |
216 | ---
217 |
218 | This file is automatically generated with [@svrooij/sonos-docs](https://github.com/svrooij/sonos-api-docs/tree/main/generator/sonos-docs), do not edit manually.
219 |
220 | | Device | Software generation | Software version | Discovery date |
221 | |:-------|:--------------------|:-----------------|:---------------|
222 | | `Sonos Play:1 (S1)` | S2 | 77.4-49290 | 2024-02-13T15:56:06.184Z |
223 | | `Sonos One (S13)` | S2 | 63.2-90210 | 2021-07-21T23:31:19.273Z |
224 | | `Sonos Beam (S14)` | S2 | 64.3-19080 | 2021-08-18T06:04:08.308Z |
225 | | `Sonos One (S18)` | S2 | 77.4-49290 | 2024-02-13T15:55:36.464Z |
226 | | `SYMFONISK Bookshelf (S21)` | S2 | 66.4-23300 | 2022-01-01T11:41:01.361Z |
227 | | `Sonos Roam (S27)` | S2 | 63.2-90210 | 2021-07-21T23:31:31.207Z |
228 | | `Sonos Play:3 (S3)` | S2 | 64.3-19080 | 2021-08-18T06:09:36.692Z |
229 | | `SYMFONISK Bookshelf (S33)` | S2 | 77.4-49290 | 2024-02-13T15:55:24.423Z |
230 | | `Sonos One SL (S38)` | S2 | 72.2-40060 | 2023-05-22T16:39:25.503Z |
231 | | `Sonos Play:5 (S6)` | S2 | 64.3-19080 | 2021-08-18T06:06:35.970Z |
232 | | `Sonos Playbar (S9)` | S2 | 77.4-49290 | 2024-02-13T15:55:46.307Z |
233 | | `Sonos Sub (Sub)` | S2 | 63.2-90210 | 2021-07-21T23:31:40.304Z |
234 |
--------------------------------------------------------------------------------
/docs/services/zone-group-topology.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | title: ZoneGroupTopology
4 | parent: Sonos Services
5 | ---
6 | # ZoneGroupTopology service
7 | {: .no_toc }
8 |
9 | Zone config stuff, eg getting all the configured sonos zones
10 |
11 | The ZoneGroupTopology service is available on these models: `Sonos Play:1 (S1) S2` / `Sonos One (S13) S2` / `Sonos Beam (S14) S2` / `Sonos One (S18) S2` / `SYMFONISK Bookshelf (S21) S2` / `Sonos Roam (S27) S2` / `Sonos Play:3 (S3) S2` / `SYMFONISK Bookshelf (S33) S2` / `Sonos One SL (S38) S2` / `Sonos Play:5 (S6) S2` / `Sonos Playbar (S9) S2` / `Sonos Sub (Sub) S2`.
12 |
13 | 1. TOC
14 | {:toc}
15 |
16 | ---
17 |
18 | ## Service data
19 | {: .no_toc }
20 |
21 | | name | value |
22 | |:-----|:------|
23 | | **Control URL** | `http://192.168.x.x:1400/ZoneGroupTopology/Control` |
24 | | **Event subscription URL** | `http://192.168.x.x:1400/ZoneGroupTopology/Event` |
25 | | **Discovery URL** | `http://192.168.x.x:1400/xml/ZoneGroupTopology1.xml` |
26 | | **Service ID** | `urn:upnp-org:serviceId:ZoneGroupTopology` |
27 | | **Service type** | `urn:schemas-upnp-org:service:ZoneGroupTopology:1` |
28 |
29 | ### Sample request
30 | {: .no_toc }
31 |
32 | ```text
33 | POST /ZoneGroupTopology/Control
34 | Host: 192.168.x.x:1400
35 | soapaction: "urn:schemas-upnp-org:service:ZoneGroupTopology:1#{ActionName}"
36 | Content-Type: text/xml; charset="utf-8"
37 |
38 |
39 |
40 |
41 | {ActionBodyHere}
42 |
43 |
44 | ```
45 |
46 | ---
47 |
48 | ## Available actions
49 |
50 | ### BeginSoftwareUpdate
51 |
52 | Action body:
53 |
54 | ```xml
55 |
56 | string
57 | ui4
58 | string
59 |
60 | ```
61 |
62 | Inputs:
63 |
64 | | parameter | type | description |
65 | |:----------|:-----|:------------|
66 | | **UpdateURL** | `string` | |
67 | | **Flags** | `ui4` | |
68 | | **ExtraOptions** | `string` | |
69 |
70 | ### CheckForUpdate
71 |
72 | Action body:
73 |
74 | ```xml
75 |
76 | string
77 | boolean
78 | string
79 |
80 | ```
81 |
82 | Inputs:
83 |
84 | | parameter | type | description |
85 | |:----------|:-----|:------------|
86 | | **UpdateType** | `string` | Allowed values: `All` / `Software` |
87 | | **CachedOnly** | `boolean` | Allowed values: `1` (= true) / `0` (= false) |
88 | | **Version** | `string` | |
89 |
90 | Outputs:
91 |
92 | | parameter | type | description |
93 | |:----------|:-----|:------------|
94 | | **UpdateItem** | `string` | |
95 |
96 | ### GetZoneGroupAttributes
97 |
98 | Get information about the current Zone
99 |
100 | Action body:
101 |
102 | ```xml
103 |
104 |
105 | ```
106 |
107 | No input arguments
108 |
109 | Outputs:
110 |
111 | | parameter | type | description |
112 | |:----------|:-----|:------------|
113 | | **CurrentZoneGroupName** | `string` | |
114 | | **CurrentZoneGroupID** | `string` | |
115 | | **CurrentZonePlayerUUIDsInGroup** | `string` | |
116 | | **CurrentMuseHouseholdId** | `string` | |
117 |
118 | ### GetZoneGroupState
119 |
120 | Get all the Sonos groups, (as XML)
121 |
122 | Action body:
123 |
124 | ```xml
125 |
126 |
127 | ```
128 |
129 | No input arguments
130 |
131 | Outputs:
132 |
133 | | parameter | type | description |
134 | |:----------|:-----|:------------|
135 | | **ZoneGroupState** | `string` | xml string, see remarks |
136 |
137 | **Remarks** Some libraries also support GetParsedZoneGroupState that parses the xml for you.
138 |
139 | ### RegisterMobileDevice
140 |
141 | Action body:
142 |
143 | ```xml
144 |
145 | string
146 | string
147 | string
148 |
149 | ```
150 |
151 | Inputs:
152 |
153 | | parameter | type | description |
154 | |:----------|:-----|:------------|
155 | | **MobileDeviceName** | `string` | |
156 | | **MobileDeviceUDN** | `string` | |
157 | | **MobileIPAndPort** | `string` | |
158 |
159 | ### ReportAlarmStartedRunning
160 |
161 | Action body:
162 |
163 | ```xml
164 |
165 |
166 | ```
167 |
168 | No input arguments
169 |
170 | ### ReportUnresponsiveDevice
171 |
172 | Action body:
173 |
174 | ```xml
175 |
176 | string
177 | string
178 |
179 | ```
180 |
181 | Inputs:
182 |
183 | | parameter | type | description |
184 | |:----------|:-----|:------------|
185 | | **DeviceUUID** | `string` | |
186 | | **DesiredAction** | `string` | Allowed values: `Remove` / `TopologyMonitorProbe` / `VerifyThenRemoveSystemwide` |
187 |
188 | ### SubmitDiagnostics
189 |
190 | Action body:
191 |
192 | ```xml
193 |
194 | boolean
195 | string
196 |
197 | ```
198 |
199 | Inputs:
200 |
201 | | parameter | type | description |
202 | |:----------|:-----|:------------|
203 | | **IncludeControllers** | `boolean` | Allowed values: `1` (= true) / `0` (= false) |
204 | | **Type** | `string` | |
205 |
206 | Outputs:
207 |
208 | | parameter | type | description |
209 | |:----------|:-----|:------------|
210 | | **DiagnosticID** | `ui4` | |
211 |
212 | ## Events
213 |
214 | The ZoneGroupTopologyService has variables that might be emitted if you subscribe to events.
215 |
216 | ### Subscribe to events
217 |
218 | ```text
219 | SUBSCRIBE /ZoneGroupTopology/Event
220 | Host: 192.168.x.x:1400
221 | callback:
222 | NT: upnp:event
223 | Timeout: Second-3600
224 | ```
225 |
226 | ### Event variables
227 |
228 | | Variable | Sends events* | type | possible values |
229 | |:---------|:-------------|:-----|:----------------|
230 | | AlarmRunSequence | ✔ | `string` | |
231 | | AreasUpdateID | ✔ | `string` | |
232 | | AvailableSoftwareUpdate | ✔ | `string` | |
233 | | DiagnosticID | | `ui4` | |
234 | | MuseHouseholdId | ✔ | `string` | |
235 | | NetsettingsUpdateID | ✔ | `string` | |
236 | | SourceAreasUpdateID | ✔ | `string` | |
237 | | ThirdPartyMediaServersX | ✔ | `string` | |
238 | | ZoneGroupID | ✔ | `string` | |
239 | | ZoneGroupName | ✔ | `string` | |
240 | | ZoneGroupState | ✔ | `string` | |
241 | | ZonePlayerUUIDsInGroup | ✔ | `string` | |
242 |
243 | If the variable has a `✔` in the Sends events column, the service discovery specifies this variable emits events. Other properties might be send as a part of `LastChange`
244 |
245 | ---
246 |
247 | This file is automatically generated with [@svrooij/sonos-docs](https://github.com/svrooij/sonos-api-docs/tree/main/generator/sonos-docs), do not edit manually.
248 |
249 | | Device | Software generation | Software version | Discovery date |
250 | |:-------|:--------------------|:-----------------|:---------------|
251 | | `Sonos Play:1 (S1)` | S2 | 77.4-49290 | 2024-02-13T15:56:06.184Z |
252 | | `Sonos One (S13)` | S2 | 63.2-90210 | 2021-07-21T23:31:19.273Z |
253 | | `Sonos Beam (S14)` | S2 | 64.3-19080 | 2021-08-18T06:04:08.308Z |
254 | | `Sonos One (S18)` | S2 | 77.4-49290 | 2024-02-13T15:55:36.464Z |
255 | | `SYMFONISK Bookshelf (S21)` | S2 | 66.4-23300 | 2022-01-01T11:41:01.361Z |
256 | | `Sonos Roam (S27)` | S2 | 63.2-90210 | 2021-07-21T23:31:31.207Z |
257 | | `Sonos Play:3 (S3)` | S2 | 64.3-19080 | 2021-08-18T06:09:36.692Z |
258 | | `SYMFONISK Bookshelf (S33)` | S2 | 77.4-49290 | 2024-02-13T15:55:24.423Z |
259 | | `Sonos One SL (S38)` | S2 | 72.2-40060 | 2023-05-22T16:39:25.503Z |
260 | | `Sonos Play:5 (S6)` | S2 | 64.3-19080 | 2021-08-18T06:06:35.970Z |
261 | | `Sonos Playbar (S9)` | S2 | 77.4-49290 | 2024-02-13T15:55:46.307Z |
262 | | `Sonos Sub (Sub)` | S2 | 63.2-90210 | 2021-07-21T23:31:40.304Z |
263 |
--------------------------------------------------------------------------------
/docs/sonos-communication.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | title: Sonos communication
4 | nav_order: 4
5 | has_toc: false
6 | ---
7 |
8 | # Sonos communication
9 |
10 | To communicate with your Sonos speakers on your local network use:
11 |
12 | - SOAP to call the SONOS services at port 1400 and subscribe to events [see services](#sonos-services)
13 | - HTTP requests at port 1400 to scrape the UPnP service information or get a simple device status information [see http requests](#http-endpoints)
14 | - UDP Datagram and Simple Service Discovery Protocol (SSDP) at port 1900 to discover SONOS player [see auto discovery](#auto-discovery)
15 | - New secure RestURL at `https://{ip}:1443/api` (not covered in this documentation)
16 |
17 | ## Sonos Services
18 |
19 | Each sonos speaker has [several soap services]({{'services/' | relative_url }}) defined. All which have several actions that can be executed. The documentation of these services is scraped from the discovery file that every sonos speaker has available at `http://{ip}:1400/xml/device_description.xml`.
20 |
21 | ## Sonos SOAP remarks
22 |
23 | - Sonos communicates booleans as `1` for true and `0` for false. This is something to keep in mind if you see **boolean** somewhere.
24 | - Some actions (like [ListAlarms]({{'services/alarm-clock.html#listalarms' | relative_url }})) return encoded xml as string. Before you can read these, you'll have to decode them and then parse them as XML. Libraries like [node-sonos-ts](https://sonos-ts.svrooij.io/sonos-device/services/alarm-clock-service.html#listalarms) provide a way that already parses the the output so you don't have to.
25 |
26 | ## SOAP call
27 |
28 | A SOAP call is just a http request, with some special headers and some xml formatted body. Each request is a `POST` request to some endpoint.
29 |
30 | In this sample we described the [SetMute]({{ '/services/rendering-control.html#setmute' | relative_url }}) command.
31 |
32 | | What | Sample |
33 | | ---- | ------ |
34 | | IP of speaker | `192.168.0.31` |
35 | | [Control endpoint]({{'/services/rendering-control.html#service-data' | relative_url }}) | `/MediaRenderer/RenderingControl/Control` |
36 | | Service type | `urn:schemas-upnp-org:service:RenderingControl:1` |
37 |
38 | You can find this information on the page describing one of [many sonos services]({{'/services/' | relative_url }}).
39 |
40 | ### SOAP call Rendering control - SetMute
41 |
42 | You do a HTTP `POST` request to the [control endpoint]({{'/services/rendering-control.html#service-data' | relative_url }}) of the `RenderingControlService`. This service has a service type of `urn:schemas-upnp-org:service:RenderingControl:1` which is needed in the `soapaction` http header and in the soap body. Where you also specify the name of the action `SetMute` in this case.
43 |
44 | URL `http://192.168.0.31:1400/MediaRenderer/RenderingControl/Control`
45 |
46 | Required HTTP headers:
47 |
48 | ```txt
49 | soapaction: "urn:schemas-upnp-org:service:RenderingControl:1#SetMute"
50 | Content-Type: text/xml; charset="utf-8"
51 | ```
52 |
53 | The body of the request has to be specified as XML. We also added the correct action body for the `SetMute` action. As you see below, booleans are converted to `1` for true and `0` for false. This is just how Sonos works.
54 |
55 | ```xml
56 |
57 |
58 |
59 |
60 | 0
61 | Master
62 | 1
63 |
64 |
65 |
66 | ```
67 |
68 | ### SOAP response
69 |
70 | All calls to sonos will return a xml object. Either with a success message of with a failure.
71 |
72 | Success message (without output parameters) to above command:
73 |
74 | ```xml
75 |
76 |
77 |
78 |
79 |
80 | ```
81 |
82 | Generic error (when deleting an alarm that doesn't exists) body (HTTP status code 500):
83 |
84 | ```xml
85 |
86 |
87 |
88 | s:Client
89 | UPnPError
90 |
91 |
92 | 800
93 |
94 |
95 |
96 |
97 |
98 | ```
99 |
100 | Sometimes you're getting a more specific error code, we tried describing all of them in the [documentation.json](https://github.com/svrooij/sonos-api-docs/blob/main/docs/documentation.json)
101 |
102 | ## HTTP Endpoints
103 |
104 | Apart from the soap services, sonos also has some http endpoints available where you can get extra information:
105 |
106 | | URL | Description |
107 | | --- | ----------- |
108 | | `http://{ip}:1400/status/info` | playerId, serialNumber, groupId, householdId, capabilities, versions and more (JSON format) |
109 | | `http://{ip}:1400/status` | several additional connection information |
110 | | `http://{ip}:1400/status/batterystatus` | battery status for devices with battery (JSON format) |
111 | | `http://{ip}:1400/region.htm` | to select a Wifi region out of USA/Canada, EU, CHINA, JAPAN, ISRAEL, RUSSIA, SOUTH KOREA |
112 | | `http://{ip}:1400/support/review` | a list of all players with playerID and links to more information |
113 | | `http://{ip}:1400/xml/device_description.xml` | Sonos services description, used by the [generator](https://github.com/svrooij/sonos-api-docs/tree/main/generator/sonos-docs) |
114 |
115 | ## Auto discovery
116 |
117 | Each sonos speaker can be discovered by the [SSDP](https://en.wikipedia.org/wiki/Simple_Service_Discovery_Protocol) or **Simple Service Discovery Protocol**.
118 | In short each speaker listens for a `ssdp:discovery` command.
119 |
120 | Which is actually just a simple UDP packet send to port `1900` on multicast address `239.255.255.250` and `255.255.255.255` with the following body:
121 |
122 | ```text
123 | M-SEARCH * HTTP/1.1
124 | HOST: 239.255.255.250:1900
125 | MAN: ssdp:discover
126 | MX: 1
127 | ST: urn:schemas-upnp-org:device:ZonePlayer:1
128 | ```
129 |
130 | By sending a this UDP multicast packet, you will get a response from all speakers available on your network. See [sonos-device-discovery.ts](https://github.com/svrooij/node-sonos-ts/blob/master/src/sonos-device-discovery.ts) for a sample on how to do that in TypeScript/Node. That should give you some pointers on how to do that in another language.
131 |
--------------------------------------------------------------------------------
/generator/sonos-docs/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | indent_style = space
5 | indent_size = 2
6 | charset = utf-8
7 | trim_trailing_whitespace = true
8 | insert_final_newline = true
9 |
10 | [*.md]
11 | trim_trailing_whitespace = false
12 |
--------------------------------------------------------------------------------
/generator/sonos-docs/.eslintignore:
--------------------------------------------------------------------------------
1 | /lib
2 |
--------------------------------------------------------------------------------
/generator/sonos-docs/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "extends": [
3 | "oclif",
4 | "oclif-typescript"
5 | ]
6 | }
7 |
--------------------------------------------------------------------------------
/generator/sonos-docs/.gitignore:
--------------------------------------------------------------------------------
1 | *-debug.log
2 | *-error.log
3 | /.nyc_output
4 | /dist
5 | /lib
6 | /tmp
7 | /yarn.lock
8 | node_modules
9 | /data/intermediate.json
10 | /.cache/combined.json
--------------------------------------------------------------------------------
/generator/sonos-docs/README.md:
--------------------------------------------------------------------------------
1 | # Sonos client generator `@svrooij/sonos-docs`
2 |
3 |
4 | CLI tool to generate documentation for the undocumented sonos api
5 |
6 | [](https://oclif.io)
7 | [](https://www.npmjs.com/package/@svrooij/sonos-docs)
8 | [](https://www.npmjs.com/package/@svrooij/sonos-docs)
9 | [](https://github.com/svrooij/sonos-api-docs/blob/master/generator/sonos-docs/package.json)
10 |
11 |
12 | * [Sonos client generator `@svrooij/sonos-docs`](#sonos-client-generator-svrooijsonos-docs)
13 | * [🏗 Usage](#-usage)
14 | * [🔨 Commands](#-commands)
15 |
16 | # 🏗 Usage
17 |
18 | ```sh-session
19 | $ npm install -g @svrooij/sonos-docs
20 | $ sonos-docs COMMAND
21 | running command...
22 | $ sonos-docs (-v|--version|version)
23 | @svrooij/sonos-docs/0.0.0 win32-x64 node-v16.8.0
24 | $ sonos-docs --help [COMMAND]
25 | USAGE
26 | $ sonos-docs COMMAND
27 | ...
28 | ```
29 |
30 |
31 | # 🔨 Commands
32 |
33 |
34 | * [`sonos-docs combine`](#sonos-docs-combine)
35 | * [`sonos-docs generate TEMPLATE OUTPUT`](#sonos-docs-generate-template-output)
36 | * [`sonos-docs help [COMMAND]`](#sonos-docs-help-command)
37 | * [`sonos-docs musicservices IP`](#sonos-docs-musicservices-ip)
38 | * [`sonos-docs services IP`](#sonos-docs-services-ip)
39 |
40 | ## `sonos-docs combine`
41 |
42 | Generate combined.json file by combining the documentation file and the discovered services.
43 |
44 | ```
45 | USAGE
46 | $ sonos-docs combine
47 |
48 | OPTIONS
49 | -h, --help show CLI help
50 |
51 | --discoveryUrl=discoveryUrl [default: https://github.com/svrooij/sonos-api-docs/raw/main/generator/sonos-docs/data/]
52 | Base url to load the discovery files from
53 |
54 | --docsFile=docsFile File location of documenation, instead of url.
55 |
56 | --docsUrl=docsUrl [default: https://raw.githubusercontent.com/svrooij/sonos-api-docs/main/docs/documentation.json] The url of the
57 | documentation, this is just to override the documentation url
58 |
59 | --folder=folder Load discovered services from this folder. Loaded from repository if empty
60 |
61 | --models=models [default: S1-1,S5-1,S9-1,S3-2,S6-2,S13-2,S14-2,S27-2,Sub-2] Models to use, separated by
62 | comma. as {model}-{softwareGen}
63 |
64 | --out=out [default: .cache/combined.json] Output filename
65 | ```
66 |
67 | _See code: [src\commands\combine.ts](https://github.com/svrooij/sonos-api-docs/blob/v0.0.0/src\commands\combine.ts)_
68 |
69 | ## `sonos-docs generate TEMPLATE OUTPUT`
70 |
71 | Generate files based on the intermediate file and a template.
72 |
73 | ```
74 | USAGE
75 | $ sonos-docs generate TEMPLATE OUTPUT
76 |
77 | ARGUMENTS
78 | TEMPLATE The template to use, either a folder relative to the current or a folder an included in the generator
79 | OUTPUT The root directory where the files should be generated
80 |
81 | OPTIONS
82 | -h, --help show CLI help
83 | -i, --intermediate=intermediate [default: data/intermediate.json] intermediate file to use. generate with 'combine'
84 | ```
85 |
86 | _See code: [src\commands\generate.ts](https://github.com/svrooij/sonos-api-docs/blob/v0.0.0/src\commands\generate.ts)_
87 |
88 | ## `sonos-docs help [COMMAND]`
89 |
90 | display help for sonos-docs
91 |
92 | ```
93 | USAGE
94 | $ sonos-docs help [COMMAND]
95 |
96 | ARGUMENTS
97 | COMMAND command to show help for
98 |
99 | OPTIONS
100 | --all see all commands in CLI
101 | ```
102 |
103 | _See code: [@oclif/plugin-help](https://github.com/oclif/plugin-help/blob/v3.2.0/src\commands\help.ts)_
104 |
105 | ## `sonos-docs musicservices IP`
106 |
107 | describe the command here
108 |
109 | ```
110 | USAGE
111 | $ sonos-docs musicservices IP
112 |
113 | ARGUMENTS
114 | IP The IP of the sonos speaker to load the music services
115 |
116 | OPTIONS
117 | -x, --extended show extra columns
118 | --columns=columns only show provided columns (comma-separated)
119 | --csv output is csv format [alias: --output=csv]
120 | --docs Show a markdown table
121 | --filter=filter filter property by partial string matching, ex: name=foo
122 | --no-header hide table header from output
123 | --no-truncate do not truncate output to fit screen
124 | --output=csv|json|yaml output in a more machine friendly format
125 | --saveJson=saveJson If set, save music services as json
126 | --show Show the music services
127 | --sort=sort property to sort by (prepend '-' for descending)
128 | ```
129 |
130 | _See code: [src\commands\musicservices.ts](https://github.com/svrooij/sonos-api-docs/blob/v0.0.0/src\commands\musicservices.ts)_
131 |
132 | ## `sonos-docs services IP`
133 |
134 | Fetch device discovery document and generate json file
135 |
136 | ```
137 | USAGE
138 | $ sonos-docs services IP
139 |
140 | ARGUMENTS
141 | IP The IP of the sonos to do service discovery for.
142 |
143 | OPTIONS
144 | -d, --dryRun
145 | -f, --folder=folder [default: data] Folder to write discovered services.
146 | -h, --help show CLI help
147 | ```
148 |
149 | _See code: [src\commands\services.ts](https://github.com/svrooij/sonos-api-docs/blob/v0.0.0/src\commands\services.ts)_
150 |
151 | * [`sonos-docs combine`](#sonos-docs-combine)
152 | * [`sonos-docs generate TEMPLATE OUTPUT`](#sonos-docs-generate-template-output)
153 | * [`sonos-docs help [COMMAND]`](#sonos-docs-help-command)
154 | * [`sonos-docs musicservices IP`](#sonos-docs-musicservices-ip)
155 | * [`sonos-docs services IP`](#sonos-docs-services-ip)
156 |
157 | ## `sonos-docs combine`
158 |
159 | Generate intermediate json file by combining the documentation file and the discovered services.
160 |
161 | ```
162 | USAGE
163 | $ sonos-docs combine
164 |
165 | OPTIONS
166 | -h, --help show CLI help
167 |
168 | --discoveryUrl=discoveryUrl [default: https://github.com/svrooij/sonos-api-docs/raw/main/generator/sonos-docs/data/]
169 | Base url to load the discovery files from
170 |
171 | --docsFile=docsFile File location of documenation, instead of url.
172 |
173 | --docsUrl=docsUrl [default: https://svrooij.io/sonos-api-docs/documentation.json] The url of the
174 | documentation, this is just to override the documentation url
175 |
176 | --folder=folder Load discovered services from this folder. Loaded from repository if empty
177 |
178 | --models=models [default: S1-1,S5-1,S9-1,S3-2,S6-2,S13-2,S14-2,S27-2,Sub-2] Models to use, separated by
179 | comma. as {model}-{softwareGen}
180 |
181 | --out=out [default: data/intermediate.json] Output filename
182 | ```
183 |
184 | _See code: [src/commands/combine.ts](https://github.com/svrooij/sonos-api-docs/blob/v0.0.0/src/commands/combine.ts)_
185 |
186 | ## `sonos-docs generate TEMPLATE OUTPUT`
187 |
188 | Generate files based on the intermediate file and a template.
189 |
190 | ```
191 | USAGE
192 | $ sonos-docs generate TEMPLATE OUTPUT
193 |
194 | ARGUMENTS
195 | TEMPLATE The template to use, either a folder relative to the current or a folder an included in the generator
196 | OUTPUT The root directory where the files should be generated
197 |
198 | OPTIONS
199 | -h, --help show CLI help
200 | -i, --combined=combined [default: .cache/combined.json] combined documentation file to use. generate with 'combine'
201 | ```
202 |
203 | _See code: [src/commands/generate.ts](https://github.com/svrooij/sonos-api-docs/blob/v1.0.0/src/commands/generate.ts)_
204 |
205 | ## `sonos-docs help [COMMAND]`
206 |
207 | display help for sonos-docs
208 |
209 | ```
210 | USAGE
211 | $ sonos-docs help [COMMAND]
212 |
213 | ARGUMENTS
214 | COMMAND command to show help for
215 |
216 | OPTIONS
217 | --all see all commands in CLI
218 | ```
219 |
220 | _See code: [@oclif/plugin-help](https://github.com/oclif/plugin-help/blob/v3.2.3/src/commands/help.ts)_
221 |
222 | ## `sonos-docs musicservices IP`
223 |
224 | describe the command here
225 |
226 | ```
227 | USAGE
228 | $ sonos-docs musicservices IP
229 |
230 | ARGUMENTS
231 | IP The IP of the sonos speaker to load the music services
232 |
233 | OPTIONS
234 | -x, --extended show extra columns
235 | --columns=columns only show provided columns (comma-separated)
236 | --csv output is csv format [alias: --output=csv]
237 | --docs Show a markdown table
238 | --filter=filter filter property by partial string matching, ex: name=foo
239 | --no-header hide table header from output
240 | --no-truncate do not truncate output to fit screen
241 | --output=csv|json|yaml output in a more machine friendly format
242 | --saveJson=saveJson If set, save music services as json
243 | --show Show the music services
244 | --sort=sort property to sort by (prepend '-' for descending)
245 | ```
246 |
247 | _See code: [src/commands/musicservices.ts](https://github.com/svrooij/sonos-api-docs/blob/v1.0.0/src/commands/musicservices.ts)_
248 |
249 | ## `sonos-docs services IP`
250 |
251 | Fetch device discovery document and generate json file
252 |
253 | ```
254 | USAGE
255 | $ sonos-docs services IP
256 |
257 | ARGUMENTS
258 | IP The IP of the sonos to do service discovery for.
259 |
260 | OPTIONS
261 | -d, --dryRun
262 | -f, --folder=folder [default: data] Folder to write discovered services.
263 | -h, --help show CLI help
264 | ```
265 |
266 | _See code: [src/commands/services.ts](https://github.com/svrooij/sonos-api-docs/blob/v1.0.0/src/commands/services.ts)_
267 |
268 |
--------------------------------------------------------------------------------
/generator/sonos-docs/bin/run:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 |
3 | require('@oclif/command').run()
4 | .then(require('@oclif/command/flush'))
5 | .catch(require('@oclif/errors/handle'))
6 |
--------------------------------------------------------------------------------
/generator/sonos-docs/bin/run.cmd:
--------------------------------------------------------------------------------
1 | @echo off
2 |
3 | node "%~dp0\run" %*
4 |
--------------------------------------------------------------------------------
/generator/sonos-docs/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@svrooij/sonos-docs",
3 | "description": "CLI tool to generate documentation for the undocumented sonos api",
4 | "version": "0.0.0-development",
5 | "author": "Stephan van Rooij (https://svrooij.io)",
6 | "bin": {
7 | "sonos-docs": "./bin/run"
8 | },
9 | "bugs": "https://github.com/svrooij/sonos-api-docs/issues",
10 | "dependencies": {
11 | "@oclif/command": "^1.8.0",
12 | "@oclif/config": "^1.17.0",
13 | "@oclif/plugin-help": "^3.2.3",
14 | "@svrooij/sonos": "2.4.1",
15 | "cli-ux": "^5.6.3",
16 | "fast-xml-parser": "^3.17.4",
17 | "handlebars": "^4.7.7",
18 | "node-fetch": "^2.6.2",
19 | "tslib": "^1.14.1"
20 | },
21 | "devDependencies": {
22 | "@oclif/dev-cli": "^1.26.0",
23 | "@types/debug": "^4.1.7",
24 | "@types/node": "^16.9.6",
25 | "@types/node-fetch": "^2.5.7",
26 | "eslint": "^5.16.0",
27 | "eslint-config-oclif": "^3.1.0",
28 | "eslint-config-oclif-typescript": "^0.1.0",
29 | "globby": "^10.0.2",
30 | "rimraf": "^3.0.2",
31 | "semantic-release": "^18.0.0",
32 | "ts-node": "^10.2.1",
33 | "typescript": "^3.9.7"
34 | },
35 | "engines": {
36 | "node": ">=8.0.0"
37 | },
38 | "files": [
39 | "/bin",
40 | "/lib",
41 | "/templates",
42 | "/npm-shrinkwrap.json",
43 | "/oclif.manifest.json"
44 | ],
45 | "homepage": "https://github.com/svrooij/sonos-api-docs/generator/sonos-docs",
46 | "keywords": [
47 | "oclif"
48 | ],
49 | "license": "MIT",
50 | "main": "lib/index.js",
51 | "oclif": {
52 | "commands": "./lib/commands",
53 | "bin": "sonos-docs",
54 | "plugins": [
55 | "@oclif/plugin-help"
56 | ]
57 | },
58 | "repository": "https://github.com/svrooij/sonos-api-docs",
59 | "scripts": {
60 | "postpack": "rimraf oclif.manifest.json",
61 | "posttest": "eslint . --ext .ts --config .eslintrc",
62 | "prepack": "rimraf lib && tsc -b && oclif-dev manifest && oclif-dev readme",
63 | "test": "echo NO TESTS",
64 | "version": "oclif-dev readme && git add README.md",
65 | "intermediate": "./bin/run combine --docsFile=../../docs/documentation.json --folder=data",
66 | "intermediate-win": ".\\bin\\run combine --docsFile=../../docs/documentation.json --folder=data",
67 | "combine-win": ".\\bin\\run combine --docsFile=../../docs/documentation.json --folder=data",
68 | "docs": "./bin/run generate docs ../../docs",
69 | "docs-win": ".\\bin\\run generate docs ../../docs"
70 | },
71 | "types": "lib/index.d.ts",
72 | "release": {
73 | "branches": [
74 | "+([0-9])?(.{+([0-9]),x}).x",
75 | "main",
76 | "next",
77 | {
78 | "name": "beta",
79 | "prerelease": true
80 | },
81 | {
82 | "name": "ci-build",
83 | "prerelease": true
84 | }
85 | ]
86 | }
87 | }
88 |
--------------------------------------------------------------------------------
/generator/sonos-docs/src/commands/generate.ts:
--------------------------------------------------------------------------------
1 | import {Command, flags} from '@oclif/command'
2 | import {cli} from 'cli-ux'
3 |
4 | import * as path from 'path'
5 | import * as fs from 'fs'
6 | import * as handlebars from 'handlebars'
7 |
8 | import SonosDevice from '../models/sonos-device'
9 | import {Template} from '../models/template'
10 | import {SonosService} from '../models/sonos-service'
11 | import StringHelper from '../helpers/string-helper'
12 | import SonosStateVariable from '../models/sonos-state-variable'
13 | import {SonosServiceActionArgument} from '../models/sonos-service-action'
14 | import ExtendedSonosDescription from '../models/extended-sonos-description'
15 |
16 | export default class Generate extends Command {
17 | static description = 'Generate files based on the intermediate file and a template.'
18 |
19 | static flags = {
20 | help: flags.help({char: 'h'}),
21 | combined: flags.string({char: 'i', description: 'combined documentation file to use. generate with \'combine\'', default: '.cache/combined.json'}),
22 | }
23 |
24 | static args = [
25 | {
26 | name: 'template',
27 | required: true,
28 | description: 'The template to use, either a folder relative to the current or a folder an included in the generator',
29 | },
30 | {
31 | name: 'output',
32 | required: true,
33 | description: 'The root directory where the files should be generated',
34 | },
35 | ]
36 |
37 | async run() {
38 | const {args, flags} = this.parse(Generate)
39 | this.log('Starting generator with template \'%s\'', args.template)
40 |
41 | const outputTemplate = this.getTemplate(args.template)
42 | const deviceDescription = this.getDeviceDescription(flags.combined, outputTemplate?.dataTypes ?? {}, outputTemplate?.serviceData)
43 |
44 | const outputBase = this.getFullPathAndCreateDirectory(args.output, true)
45 |
46 | if (outputTemplate === undefined || deviceDescription === undefined) {
47 | // This should never be reached, since it will already throw an error earlier.
48 | return
49 | }
50 |
51 | // Register helpers
52 | // {{lower var}} for lowercase
53 | handlebars.registerHelper('lower', (input: any) => {
54 | if (typeof input === 'string') {
55 | return input.toLowerCase()
56 | }
57 | return input
58 | })
59 | // {{kebab var}} for kebab case
60 | handlebars.registerHelper('kebab', (input: any) => {
61 | if (typeof input === 'string') {
62 | return StringHelper.camelToKebab(input)
63 | }
64 | return input
65 | })
66 | // unless val
67 | handlebars.registerHelper('are_equal', function (input?: string, compareTo?: string) {
68 | if (arguments.length !== 3) {
69 | throw new handlebars.Exception('same requires exactly two argument')
70 | }
71 | // console.log('Compare items', arguments);
72 | return input === compareTo
73 | })
74 | handlebars.registerHelper('or', function (condition1: boolean, condition2: boolean) {
75 | if (arguments.length !== 3) {
76 | throw new handlebars.Exception('or requires exactly two argument')
77 | }
78 | return condition1 || condition2
79 | })
80 | handlebars.registerHelper('sonos_if_only_instance_id', function (input?: Array, defaultParams?: string) {
81 | if (input !== undefined && defaultParams !== undefined && input.length === 1 && input[0].name === 'InstanceID') {
82 | return defaultParams
83 | }
84 | return null
85 | })
86 | handlebars.registerHelper('ends_with', function (input?: string, endsWith?: string) {
87 | if (arguments.length !== 3) {
88 | throw new handlebars.Exception('same requires exactly two argument')
89 | }
90 | if (endsWith === undefined) {
91 | throw new handlebars.Exception('2nd parameter has to be a string')
92 | }
93 |
94 | return input?.endsWith(endsWith) == true;
95 | })
96 |
97 | outputTemplate?.files.forEach(t => {
98 | if (t.usage === 'index') {
99 | cli.action.start(`Creating '${t.outputFile}' from template ${t.file}`)
100 | const template = this.getHandlebarTemplate(outputTemplate.folder, t.file)
101 | const result = template(deviceDescription)
102 | const outputfile = path.join(outputBase, t.outputFile)
103 | fs.writeFileSync(outputfile, result)
104 | cli.action.stop()
105 | } else {
106 | cli.action.start(`Creating services '${t.outputFile}' from template '${t.file}'`)
107 | const template = this.getHandlebarTemplate(outputTemplate.folder, t.file)
108 | deviceDescription.services.forEach(s => {
109 | const outputfile = path.join(outputBase, t.outputFile.replace('{snService}', s.kebabName ?? '').replace('{service}', s.name))
110 | const folder = path.dirname(outputfile)
111 | if (!fs.existsSync(folder)) {
112 | fs.mkdirSync(folder, {recursive: true})
113 | }
114 | const result = template(s)
115 | fs.writeFileSync(outputfile, result)
116 | })
117 | cli.action.stop()
118 | }
119 | })
120 | }
121 |
122 | private getFullPathAndCreateDirectory(location: string, createFolder = false) {
123 | const filename = path.isAbsolute(location) ? location : path.join(process.cwd(), location)
124 | const folder = path.dirname(filename)
125 | if (createFolder && !fs.existsSync(folder)) {
126 | fs.mkdirSync(folder, {recursive: true})
127 | }
128 |
129 | return filename
130 | }
131 |
132 | private getTemplate(name: string): Template | undefined | never {
133 | // Template relative to current folder;
134 | let folder = path.isAbsolute(name) ? name : path.join(process.cwd(), name)
135 | let filename = path.join(folder, 'template.json')
136 | if (fs.existsSync(filename)) {
137 | const template = JSON.parse(fs.readFileSync(filename).toString()) as Template
138 | template.folder = folder
139 | this.log('Using local template: \'%s\' from: %s ', template.name ?? template.slug, folder)
140 | return template
141 | }
142 |
143 | folder = path.join(__dirname, '..', '..', 'templates', name)
144 | filename = path.join(folder, 'template.json')
145 |
146 | if (fs.existsSync(filename)) {
147 | const template = JSON.parse(fs.readFileSync(filename).toString()) as Template
148 | template.folder = folder
149 | this.log('Using packaged template: \'%s\'', template.name ?? template.slug)
150 | return template
151 | }
152 |
153 | return this.error('Template %s not found, use folder name or packaged template name', {exit: 20})
154 | }
155 |
156 | private postProcess(input: string): string {
157 | // Do some post-processing on the template. HandlebarsJS doesn't support Outputting these chars '{' and '}'
158 | return input.replace(/-{-/g, '{').replace(/-}-/g, '}')
159 | }
160 |
161 | private getDeviceDescription(location: string, dataTypes: { [key: string]: string }, serviceData?: { [key: string]: any }): ExtendedSonosDescription | undefined | never {
162 | const intermediateFile = this.getFullPathAndCreateDirectory(location)
163 | if (!fs.existsSync(intermediateFile)) {
164 | return this.error('Combined documentation file doesn\'t exist, generate with \'combine\' command first.', {exit: 10})
165 | }
166 |
167 | // Set relatedStateVariables to correct value.
168 | const intermediate = JSON.parse(fs.readFileSync(intermediateFile).toString()) as ExtendedSonosDescription
169 | intermediate.services.forEach(service => {
170 | service.kebabName = StringHelper.camelToKebab(service.name.replace('AV', 'Av').replace('HT', 'Ht'))
171 | if (typeof (service.stateVariables) !== undefined) {
172 | // Replace datatypes as specified in the template
173 | if (dataTypes !== undefined) {
174 | service.stateVariables?.forEach(v => {
175 | v.dataType = this.getCorrectDataType(v.name, dataTypes) ?? dataTypes[v.dataType] ?? v.dataType
176 | })
177 | }
178 | service.eventVariables = service.stateVariables?.filter((v: SonosStateVariable) => !v.name.startsWith('A_ARG_TYPE')).sort((a, b) => a.name.localeCompare(b.name))
179 | }
180 | if (typeof (service.stateVariables) !== undefined && typeof (service.actions) !== undefined) {
181 | service.outputVariables = {}
182 | service.actions?.forEach(a => {
183 | a.inputs?.forEach(i => {
184 | i.relatedStateVariable = service.stateVariables?.find(v => v.name === i.relatedStateVariableName)
185 | })
186 | a.outputs?.forEach(o => {
187 | o.relatedStateVariable = service.stateVariables?.find(v => v.name === o.relatedStateVariableName)
188 | if (o.relatedStateVariable) {
189 | // @ts-ignore
190 | service.outputVariables[o.name] = this.getCorrectDataType(o.relatedStateVariable.name, dataTypes) ?? dataTypes[o.relatedStateVariable.dataType] ?? o.relatedStateVariable.dataType;
191 | }
192 | })
193 | })
194 | if (Object.keys(service.outputVariables).length === 0) {
195 | delete service.outputVariables
196 | }
197 | }
198 | if (serviceData !== undefined) {
199 | service.data = serviceData[service.serviceName]
200 | }
201 | })
202 | intermediate.services = intermediate.services.sort((a, b) => a.name.localeCompare(b.name))
203 | return intermediate
204 | }
205 |
206 | private getHandlebarTemplate(folder: string | undefined, file: string): HandlebarsTemplateDelegate | never {
207 | if (folder === undefined) {
208 | return this.error('Template isn\'t loaded correctly', {exit: 1})
209 | }
210 |
211 | const filename = path.join(folder, file)
212 | if (!fs.existsSync(filename)) {
213 | return this.error(`Template file ${file} could not be loaded`, {exit: 30})
214 | }
215 | return handlebars.compile(fs.readFileSync(filename).toString())
216 | }
217 |
218 | private getCorrectDataType(name: string, dataTypes: { [key: string]: string }): string | undefined {
219 | const type = Object.entries(dataTypes).find(e => name.endsWith(e[0]))
220 | if (type !== undefined) {
221 | return type[1]
222 | }
223 | }
224 | }
225 |
--------------------------------------------------------------------------------
/generator/sonos-docs/src/commands/musicservices.ts:
--------------------------------------------------------------------------------
1 | import {Command, flags} from '@oclif/command'
2 | import {cli} from 'cli-ux'
3 | import { SonosDevice } from '@svrooij/sonos'
4 | import * as path from 'path'
5 | import * as fs from 'fs'
6 |
7 | export default class Musicservices extends Command {
8 | static description = 'List music services available on a Sonos speaker'
9 |
10 | static flags = {
11 | ...cli.table.flags(),
12 | show: flags.boolean({ description: 'Show the music services' }),
13 | docs: flags.boolean({ description: 'Show a markdown table' }),
14 | saveJson: flags.string({ description: 'If set, save music services as json' })
15 | }
16 |
17 | static args = [{name: 'ip', description: 'The IP of the sonos speaker to load the music services', required: true }]
18 |
19 | async run() {
20 | const {args, flags} = this.parse(Musicservices)
21 | cli.action.start(`Loading music services from ${args.ip}`)
22 | const device = new SonosDevice(args.ip);
23 |
24 | const musicServices = await device.MusicServicesService.ListAndParseAvailableServices()
25 | cli.action.stop();
26 |
27 | if(flags.saveJson !== undefined) {
28 | cli.action.start(`Saving music services to ${flags.saveJson}`)
29 | const filename = this.getFullPathAndCreateDirectory(flags.saveJson);
30 | fs.writeFileSync(filename, JSON.stringify(musicServices, null, 2))
31 | cli.action.stop();
32 | }
33 |
34 | if(flags.docs) {
35 | console.log('| Id | Name | Auth | Url |\r\n|:----|:--------------------------|:-----------|:----|');
36 | musicServices.forEach(m => {
37 | console.log(`| ${m.Id.toString().padStart(3, ' ')} | ${m.Name.padEnd(25, ' ')} | ${m.Policy.Auth.padEnd(10, ' ')} | \`${m.SecureUri}\` |`);
38 | })
39 | }
40 |
41 | if(flags.show){
42 | cli.table(musicServices, {
43 | Id: {},
44 | Name: {},
45 | Authentication: {
46 | get: row => row.Policy.Auth
47 | },
48 | Capabilities: {},
49 | Uri: { extended: true, get: row => row.SecureUri }
50 | }, {
51 | ...flags
52 | })
53 | }
54 |
55 |
56 | }
57 |
58 | private getFullPathAndCreateDirectory(location: string, createFolder = false) {
59 | const filename = path.isAbsolute(location) ? location : path.join(process.cwd(), location)
60 | const folder = path.dirname(filename)
61 | if (createFolder && !fs.existsSync(folder)) {
62 | fs.mkdirSync(folder, {recursive: true})
63 | }
64 |
65 | return filename
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/generator/sonos-docs/src/commands/services.ts:
--------------------------------------------------------------------------------
1 | import {Command, flags} from '@oclif/command'
2 | import fetch from 'node-fetch'
3 | import {parse} from 'fast-xml-parser'
4 | import * as path from 'path'
5 | import * as fs from 'fs'
6 |
7 | import SonosDevice from '../models/sonos-device'
8 | import {SonosService} from '../models/sonos-service'
9 | import SonosStateVariable from '../models/sonos-state-variable'
10 | import ArrayHelper from '../helpers/array-helper'
11 | import {SonosServiceAction, SonosServiceActionArgument} from '../models/sonos-service-action'
12 |
13 | export default class Services extends Command {
14 | static description = 'Fetch device discovery document and generate json file'
15 |
16 | static flags = {
17 | help: flags.help({char: 'h'}),
18 | folder: flags.string({char: 'f', description: 'Folder to write discovered services.', default: 'data'}),
19 | dryRun: flags.boolean({char: 'd'}),
20 | }
21 |
22 | static args = [
23 | { name: 'ip', required: true, description: 'The IP of the sonos to do service discovery for.' },
24 | ]
25 |
26 | async run() {
27 | const {args, flags} = this.parse(Services)
28 |
29 | this.log(`Discovering UPNP services from ${args.ip}`)
30 | const description = await this.loadDescription(args.ip)
31 | this.debug('Sonos device loaded', description)
32 | const folder = path.isAbsolute(flags.folder) ? flags.folder : path.join(process.cwd(), flags.folder)
33 | const file = path.join(folder, `sonos-${description.model}-${description.softwareGeneration}.json`)
34 | this.log('Saving discovered services to ', file)
35 | if (!fs.existsSync(folder)) {
36 | this.log('Output folder doesn\'t exists')
37 | fs.mkdirSync(folder, {recursive: true})
38 | }
39 |
40 | fs.writeFileSync(file, JSON.stringify(description, undefined, 2))
41 | }
42 |
43 | private createUrl(ip: string, path: string): string {
44 | return `http://${ip}:1400${path}`
45 | }
46 |
47 | private async loadDescription(ip: string): Promise {
48 | const resp = await this.fetchAndParse(this.createUrl(ip, '/xml/device_description.xml'))
49 |
50 | const desc = resp.root.device
51 | this.log(`Discovering services from ${desc.modelDescription}`)
52 |
53 | // this.log(desc.deviceList.device)
54 | const serviceDescriptions: Array = desc.serviceList.service
55 | desc.deviceList.device.forEach((d: any) => {
56 | d.serviceList.service.forEach((s: any) => {
57 | serviceDescriptions.push(s)
58 | })
59 | })
60 |
61 | // This service is duplicated in the device discovery
62 | const serviceToSkip = '/MediaServer/ConnectionManager/Control'
63 |
64 | const services = await Promise.all(serviceDescriptions
65 | .filter((serviceDescription: any) => serviceDescription.controlURL !== serviceToSkip)
66 | .map((service: any) => this.loadService(ip, service)))
67 |
68 | return {
69 | model: desc.modelNumber,
70 | modelDescription: desc.modelDescription,
71 | softwareGeneration: desc.swGen,
72 | softwareVersion: desc.softwareVersion,
73 | discoveryDate: new Date(),
74 | services: services.sort((a, b) => a.name.localeCompare(b.name)),
75 | }
76 | }
77 |
78 | private async loadService(ip: string, service: any): Promise {
79 | const name = service.serviceId.substring(service.serviceId.lastIndexOf(':') + 1)
80 | const resp = await this.fetchAndParse(this.createUrl(ip, service.SCPDURL))
81 | const desc = resp.scpd
82 | // this.log('Parsing service');
83 | // this.log(desc.actionList.action);
84 | return {
85 | name: name,
86 | serviceName: `${name}Service`,
87 | discoveryUri: service.SCPDURL,
88 | serviceId: service.serviceId,
89 | serviceType: service.serviceType,
90 | controlURL: service.controlURL,
91 | eventSubURL: service.eventSubURL,
92 | stateVariables: ArrayHelper.forceArray(desc.serviceStateTable.stateVariable).map((v: any): SonosStateVariable => {
93 | return {
94 | name: v.name,
95 | dataType: v.dataType,
96 | sendEvents: v._sendEvents === 'yes', // This probably is incorrect, sonos doesnt specify if it sends events for all properties.
97 | allowedValues: v.allowedValueList?.allowedValue,
98 | }
99 | }),
100 | actions: ArrayHelper.forceArray(desc.actionList.action).map((action: any): SonosServiceAction => {
101 | const sonosArgs = ArrayHelper.forceArray(action.argumentList?.argument ?? []).map((a: any): SonosServiceActionArgument => {
102 | return {
103 | name: a.name,
104 | direction: a.direction,
105 | relatedStateVariableName: a.relatedStateVariable,
106 | }
107 | })
108 | const inputs = sonosArgs.filter(a => a.direction === 'in')
109 | const outputs = sonosArgs.filter(a => a.direction === 'out')
110 | return {
111 | name: action.name,
112 | inputs: inputs.length > 0 ? inputs : undefined,
113 | outputs: outputs.length > 0 ? outputs : undefined,
114 | }
115 | }),
116 | }
117 | }
118 |
119 | private async fetchAndParse(url: string): Promise {
120 | return fetch(url)
121 | .then(resp => {
122 | if (resp.ok) {
123 | return resp.text()
124 | }
125 |
126 | throw new Error(`Error loading ${url} ${resp.status} ${resp.statusText}`)
127 | })
128 | .then(resp => parse(resp, {ignoreAttributes: false, attributeNamePrefix: '_'}))
129 | }
130 | }
131 |
--------------------------------------------------------------------------------
/generator/sonos-docs/src/helpers/array-helper.ts:
--------------------------------------------------------------------------------
1 | export default class ArrayHelper {
2 | static forceArray(input: TResponse | Array): Array {
3 | return Array.isArray(input) ? input : [input];
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/generator/sonos-docs/src/helpers/string-helper.ts:
--------------------------------------------------------------------------------
1 | export default class StringHelper {
2 | public static camelToKebab(input: string): string {
3 | return `${input[0].toLowerCase()}${input.slice(1)}`.replace(/([a-z0-9]|(?=[A-Z]))([A-Z])/g, '$1-$2').toLowerCase();
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/generator/sonos-docs/src/index.ts:
--------------------------------------------------------------------------------
1 | export {run} from '@oclif/command'
2 |
--------------------------------------------------------------------------------
/generator/sonos-docs/src/models/author.ts:
--------------------------------------------------------------------------------
1 | export default interface Author {
2 | name: string;
3 | mail?: string;
4 | link?: string;
5 | }
6 |
--------------------------------------------------------------------------------
/generator/sonos-docs/src/models/extended-sonos-description.ts:
--------------------------------------------------------------------------------
1 | import SonosDevice from './sonos-device'
2 | import SonosDiscoveryInfo from './sonos-discovery-info'
3 |
4 | export default interface ExtendedSonosDescription extends SonosDevice {
5 | deviceInfo: SonosDiscoveryInfo[];
6 | }
7 |
--------------------------------------------------------------------------------
/generator/sonos-docs/src/models/sonos-device.ts:
--------------------------------------------------------------------------------
1 | import {SonosService} from './sonos-service';
2 | import SonosServiceError from './sonos-service-error';
3 |
4 | export default interface SonosDevice {
5 | model: string;
6 | modelDescription: string;
7 | softwareGeneration: number;
8 | softwareVersion: string;
9 | discoveryDate: Date;
10 | services: SonosService[];
11 | errors?: SonosServiceError[];
12 | }
13 |
--------------------------------------------------------------------------------
/generator/sonos-docs/src/models/sonos-discovery-info.ts:
--------------------------------------------------------------------------------
1 | export default interface SonosDiscoveryInfo {
2 | discoveryDate: Date;
3 | model: string;
4 | modelDescription: string;
5 | softwareGeneration: number;
6 | softwareVersion: string;
7 | }
8 |
--------------------------------------------------------------------------------
/generator/sonos-docs/src/models/sonos-service-action.ts:
--------------------------------------------------------------------------------
1 | import SonosStateVariable from "./sonos-state-variable";
2 |
3 | export interface SonosServiceAction {
4 | name: string;
5 | inputs?: SonosServiceActionArgument[];
6 | outputs?: SonosServiceActionArgument[];
7 | description?: string;
8 | remarks?: string;
9 | availableAt?: string[];
10 | }
11 |
12 | export interface SonosServiceActionArgument {
13 | name: string;
14 | direction: 'in' | 'out';
15 | relatedStateVariableName: string;
16 | relatedStateVariable?: SonosStateVariable;
17 | description?: string;
18 | sample?: unknown;
19 | }
20 |
--------------------------------------------------------------------------------
/generator/sonos-docs/src/models/sonos-service-documentation.ts:
--------------------------------------------------------------------------------
1 | import SonosServiceError from './sonos-service-error';
2 | import SonosStateVariable from './sonos-state-variable';
3 |
4 | export interface SonosServicesDocumentation {
5 | services: { [key: string]: SonosServiceDocumentation };
6 | errors?: SonosServiceError[];
7 | }
8 |
9 | export interface SonosServiceDocumentation {
10 | description?: string;
11 | files?: { [key: string]: string};
12 | actions?: { [key: string]: SonosServiceDocumentationAction };
13 | customTypes?: { [key: string]: { [key: string]: string } };
14 | errors?: SonosServiceError[];
15 | variables?: SonosStateVariable[];
16 | }
17 |
18 | export interface SonosServiceDocumentationAction {
19 | description?: string;
20 | remarks?: string;
21 | params?: { [key: string]: string };
22 | sample?: { [key: string]: string };
23 | }
24 |
--------------------------------------------------------------------------------
/generator/sonos-docs/src/models/sonos-service-error.ts:
--------------------------------------------------------------------------------
1 | export default interface SonosServiceError {
2 | code: number;
3 | description: string;
4 | }
5 |
--------------------------------------------------------------------------------
/generator/sonos-docs/src/models/sonos-service.ts:
--------------------------------------------------------------------------------
1 | import SonosDiscoveryInfo from './sonos-discovery-info'
2 | import {SonosServiceAction} from './sonos-service-action'
3 | import SonosServiceError from './sonos-service-error'
4 | import SonosStateVariable from './sonos-state-variable'
5 |
6 | export interface SonosService {
7 | name: string;
8 | kebabName?: string;
9 | serviceName: string;
10 | discoveryUri: string;
11 |
12 | serviceId: string;
13 | serviceType: string;
14 | controlURL: string;
15 | eventSubURL: string;
16 |
17 | description?: string;
18 | availableAt?: string[];
19 |
20 | stateVariables?: SonosStateVariable[];
21 | actions?: SonosServiceAction[];
22 | eventVariables?: SonosStateVariable[];
23 | outputVariables?: {[key: string]: string};
24 | data?: { [key: string]: any };
25 |
26 | errors?: SonosServiceError[];
27 | deviceInfo?: SonosDiscoveryInfo[];
28 | }
29 |
30 |
--------------------------------------------------------------------------------
/generator/sonos-docs/src/models/sonos-state-variable.ts:
--------------------------------------------------------------------------------
1 | export default interface SonosStateVariable {
2 | name: string;
3 | sendEvents: boolean;
4 | dataType: string;
5 | allowedValues?: string[];
6 | description?: string;
7 | }
8 |
--------------------------------------------------------------------------------
/generator/sonos-docs/src/models/template.ts:
--------------------------------------------------------------------------------
1 | import Author from './author';
2 |
3 | export interface Template {
4 | author: Author;
5 | files: TemplateFile[];
6 | name?: string;
7 | slug: string;
8 | license: string;
9 | folder?: string;
10 | dataTypes?: { [key: string]: string }
11 | serviceData?: { [key: string]: any }
12 | }
13 |
14 | export interface TemplateFile {
15 | file: string;
16 | outputFile: string;
17 | usage: 'index' | 'service';
18 | }
19 |
--------------------------------------------------------------------------------
/generator/sonos-docs/templates/docs/service.hbs:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | title: {{name}}
4 | parent: Sonos Services
5 | ---
6 | # {{name}} service
7 | {: .no_toc }
8 | {{#if description}}
9 |
10 | {{{description}}}
11 | {{/if}}
12 |
13 | {{#if availableAt}}
14 | The {{name}} service is available on these models: {{#each deviceInfo}}`{{modelDescription}} ({{model}}) S{{softwareGeneration}}`{{#unless @last}} / {{/unless}}{{/each}}.
15 | {{/if}}
16 |
17 | 1. TOC
18 | {:toc}
19 |
20 | ---
21 |
22 | ## Service data
23 | {: .no_toc }
24 |
25 | | name | value |
26 | |:-----|:------|
27 | | **Control URL** | `http://192.168.x.x:1400{{controlURL}}` |
28 | | **Event subscription URL** | `http://192.168.x.x:1400{{eventSubURL}}` |
29 | | **Discovery URL** | `http://192.168.x.x:1400{{discoveryUri}}` |
30 | | **Service ID** | `{{serviceId}}` |
31 | | **Service type** | `{{serviceType}}` |
32 |
33 | ### Sample request
34 | {: .no_toc }
35 |
36 | ```text
37 | POST {{controlURL}}
38 | Host: 192.168.x.x:1400
39 | soapaction: "{{serviceType}}#{ActionName}"
40 | Content-Type: text/xml; charset="utf-8"
41 |
42 |
43 |
44 |
45 | {ActionBodyHere}
46 |
47 |
48 | ```
49 |
50 | ---
51 |
52 | ## Available actions
53 |
54 | {{#each actions}}
55 | ### {{name}}
56 | {{#if description}}
57 |
58 | {{{description}}}
59 | {{/if}}
60 |
61 | Action body:
62 |
63 | ```xml
64 |
65 | {{#each inputs}}
66 | <{{name}}>{{#if sample}}{{sample}}{{else}}{{relatedStateVariable.dataType}}{{/if}}{{name}}>
67 | {{/each}}
68 |
69 | ```
70 | {{#if inputs}}
71 |
72 | Inputs:
73 |
74 | | parameter | type | description |
75 | |:----------|:-----|:------------|
76 | {{#each inputs}}
77 | | **{{name}}** | `{{relatedStateVariable.dataType}}` | {{{description}}}{{#if (are_equal relatedStateVariable.dataType 'boolean')}} Allowed values: `1` (= true) / `0` (= false) {{/if}}{{#if relatedStateVariable.allowedValues}} Allowed values: {{#each relatedStateVariable.allowedValues}}`{{this}}`{{#unless @last}} / {{/unless}}{{/each}}{{/if}}{{#if (ends_with name 'MetaData')}} Embedded XML{{/if}} |
78 | {{/each}}
79 | {{else}}
80 |
81 | No input arguments
82 | {{/if}}
83 | {{#if outputs}}
84 |
85 | Outputs:
86 |
87 | | parameter | type | description |
88 | |:----------|:-----|:------------|
89 | {{#each outputs}}
90 | | **{{name}}** | `{{relatedStateVariable.dataType}}` | {{{description}}}{{#if (are_equal relatedStateVariable.dataType 'boolean')}} `1` for true and `0` for false {{/if}}{{#if relatedStateVariable.allowedValues}} Possible values: {{#each relatedStateVariable.allowedValues}}`{{this}}`{{#unless @last}} / {{/unless}}{{/each}}{{/if}}{{#if (ends_with name 'MetaData')}} Embedded XML{{/if}} |
91 | {{/each}}
92 | {{/if}}
93 | {{#if remarks}}
94 |
95 | **Remarks** {{{remarks}}}
96 | {{/if}}
97 |
98 | {{/each}}
99 | {{#if eventVariables}}
100 | ## Events
101 |
102 | The {{serviceName}} has variables that might be emitted if you subscribe to events.
103 |
104 | ### Subscribe to events
105 |
106 | ```text
107 | SUBSCRIBE {{eventSubURL}}
108 | Host: 192.168.x.x:1400
109 | callback:
110 | NT: upnp:event
111 | Timeout: Second-3600
112 | ```
113 |
114 | ### Event variables
115 |
116 | | Variable | Sends events* | type | possible values |
117 | |:---------|:-------------|:-----|:----------------|
118 | {{#each eventVariables}}
119 | | {{name}} | {{#if sendEvents}}✔{{/if}} | `{{dataType}}` | {{#if (are_equal dataType 'boolean')}} `1` for true and `0` for false {{/if}}{{#each allowedValues}}`{{this}}`{{#unless @last}} / {{/unless}}{{/each}}{{#if (ends_with name 'MetaData')}} Embedded XML{{/if}} |
120 | {{/each}}
121 |
122 | If the variable has a `✔` in the Sends events column, the service discovery specifies this variable emits events. Other properties might be send as a part of `LastChange`
123 | {{/if}}
124 | {{#if errors}}
125 |
126 | ## Custom errors
127 |
128 | The {{serviceName}} has the following known custom errors.
129 |
130 | | Error code | Description |
131 | |:-----------|:------------|
132 | {{#each errors}}
133 | | `{{code}}` | {{{description}}} |
134 | {{/each}}
135 | {{/if}}
136 |
137 | ---
138 |
139 | This file is automatically generated with [@svrooij/sonos-docs](https://github.com/svrooij/sonos-api-docs/tree/main/generator/sonos-docs), do not edit manually.
140 |
141 | | Device | Software generation | Software version | Discovery date |
142 | |:-------|:--------------------|:-----------------|:---------------|
143 | {{#each deviceInfo}}
144 | | `{{modelDescription}} ({{model}})` | S{{softwareGeneration}} | {{softwareVersion}} | {{discoveryDate}} |
145 | {{/each}}
146 |
--------------------------------------------------------------------------------
/generator/sonos-docs/templates/docs/services-index.hbs:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | title: Sonos Services
4 | has_children: true
5 | nav_order: 5
6 | has_toc: false
7 | ---
8 |
9 | # Sonos SOAP Services
10 | {: .no_toc }
11 |
12 | Every sonos speaker has several soap services. Each service has one or more actions you can call.
13 |
14 | ## UPNP specifications
15 |
16 | Sonos speaker follow the [MediaServer:4 and MediaRenderer:3 specifications](https://openconnectivity.org/developer/specifications/upnp-resources/upnp/mediaserver4-and-mediarenderer3/) by the [Open Connectivity Foundation](https://openconnectivity.org/).
17 | These documents can provide you with some extra guidelines. More details can be found at [Sonos communication](\{{'/sonos-communication.html' | relative_url }}), which show you how to exactly do a call to the sonos speakers.
18 |
19 | ## All available services
20 | {: .no_toc }
21 |
22 | | Service | Description |
23 | |:--------|:------------|
24 | {{#each services}}
25 | | [**{{name}}**]({{kebabName}}.html) | {{description}} |
26 | {{/each}}
27 | {{#if errors}}
28 |
29 | ## UPNP errors
30 |
31 | These are the default UPNP errors.
32 |
33 | | Error code | Description |
34 | |:-----------|:------------|
35 | {{#each errors}}
36 | | `{{code}}` | {{description}} |
37 | {{/each}}
38 | {{/if}}
39 |
40 | ---
41 |
42 | This file is automatically generated with [@svrooij/sonos-docs](https://github.com/svrooij/sonos-api-docs/tree/main/generator/sonos-docs), do not edit manually.
43 |
44 | | Device | Software generation | Software version | Discovery date |
45 | |:-------|:--------------------|:-----------------|:---------------|
46 | {{#each deviceInfo}}
47 | | `{{modelDescription}} ({{model}})` | S{{softwareGeneration}} | {{softwareVersion}} | {{discoveryDate}} |
48 | {{/each}}
49 |
--------------------------------------------------------------------------------
/generator/sonos-docs/templates/docs/template.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://svrooij.io/sonos-api-docs/schema/template.json",
3 | "name": "Sonos local UPNP documentation",
4 | "slug": "docs",
5 | "author": {
6 | "name": "svrooij",
7 | "link": "https://svrooij.io"
8 | },
9 | "files": [
10 | {
11 | "file": "service.hbs",
12 | "outputFile": "services/{snService}.md",
13 | "usage":"service"
14 | },
15 | {
16 | "file": "services-index.hbs",
17 | "outputFile": "services/index.md",
18 | "usage": "index"
19 | }
20 | ],
21 | "license": "MIT"
22 | }
--------------------------------------------------------------------------------
/generator/sonos-docs/templates/node/README.md:
--------------------------------------------------------------------------------
1 | # node-sonos template
2 |
3 | This folder contains the template files for [node-sonos](://github.com/bencevans/node-sonos), and is not used in the actual library just yet.
4 |
5 | ## Folder content
6 |
7 | | File | Description | Remarks |
8 | |:-----|:------------|:--------|
9 | | [service](./service.hbs) | Single service | Strong type service template |
10 |
11 | ## Use this template
12 |
13 | To use this template you'll need both this generator and node-sonos checked out.
14 |
15 | ```shell
16 | # generate the intermediate file (this will take the online documentation file)
17 | ./generator/sonos-docs/bin/run combine
18 |
19 | # Make sure you don't have any changes in node-sonos, that makes it unclear what the generator changed
20 | # generate the service files (set the correct root folder for node-sonos)
21 | ./generator/sonos-docs/bin/run generate node ../node-sonos
22 | ```
23 |
24 | ## Generator
25 |
26 | See the generator documentation [here](https://github.com/svrooij/sonos-api-docs/tree/main/generator/sonos-docs).
27 |
--------------------------------------------------------------------------------
/generator/sonos-docs/templates/node/service.hbs:
--------------------------------------------------------------------------------
1 | const Service = require('./Service')
2 | /**
3 | * Sonos {{serviceName}}
4 | {{#if description}}
5 | *
6 | * {{description}}
7 | {{/if}}
8 | *
9 | * @author Stephan van Rooij - https://svrooij.io
10 | * @remarks This file is generated, do not edit manually. https://svrooij.io/sonos-api-docs
11 | * @export
12 | * @class {{serviceName}}
13 | * @extends {Service}
14 | */
15 | class {{serviceName}} extends Service {
16 | constructor (host, port) {
17 | super()
18 | this.name = '{{name}}'
19 | this.host = host
20 | this.port = port || 1400
21 | this.controlURL = '{{controlURL}}'
22 | this.eventSubURL = '{{eventSubURL}}'
23 | this.SCPDURL = '{{discoveryUri}}'
24 | }
25 |
26 | // #region actions
27 | {{#each actions}}
28 | /**
29 | * {{name}}{{#if description}} - {{description}}{{/if}}
30 | {{#if inputs}}
31 | *
32 | * @param {Object} [options] - An object with the following properties
33 | {{/if}}
34 | {{#each inputs}}
35 | * @param { {{~ relatedStateVariable.dataType ~}} } options.{{name}}{{#if description}} - {{{description}}}{{/if}}{{#if relatedStateVariable.allowedValues}} [ {{#each relatedStateVariable.allowedValues}}'{{this}}'{{#unless @last}} / {{/unless}}{{/each}} ]{{/if}}
36 | {{/each}}
37 | {{#if remarks}}
38 | * @remarks {{{remarks}}}
39 | {{/if}}
40 | {{#if outputs}}
41 | * @returns {Object} response object, with these properties {{#each outputs}}'{{name}}'{{#unless @last}}, {{/unless}}{{/each}}
42 | {{/if}}
43 | */
44 | {{#if inputs}}
45 | async {{name}} (options{{{sonos_if_only_instance_id inputs ' = { InstanceID: 0 }'}}}) { return this._request('{{name}}', options) }
46 | {{else}}
47 | async {{name}} () { return this._request('{{name}}') }
48 | {{/if}}
49 | {{#unless @last}}
50 |
51 | {{/unless}}
52 | {{/each}}
53 | // #endregion
54 | }
55 |
56 | module.exports = {{serviceName}}
57 |
--------------------------------------------------------------------------------
/generator/sonos-docs/templates/node/template.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://svrooij.io/sonos-api-docs/schema/template.json",
3 | "name": "Node sonos",
4 | "slug": "node",
5 | "repository": "https://github.com/bencevans/node-sonos/",
6 | "author": {
7 | "name": "svrooij",
8 | "link": "https://svrooij.io"
9 | },
10 | "files": [
11 | {
12 | "file": "service.hbs",
13 | "outputFile": "lib/services/{snService}.service.js",
14 | "usage":"service"
15 | }
16 | ],
17 | "dataTypes": {
18 | "ui4": "number",
19 | "i4": "number",
20 | "ui2": "number",
21 | "i2": "number",
22 | "MetaData": "string",
23 | "ZoneGroupState": "string"
24 | },
25 | "serviceData": {
26 |
27 | },
28 | "license": "MIT"
29 | }
30 |
--------------------------------------------------------------------------------
/generator/sonos-docs/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "declaration": true,
4 | "importHelpers": true,
5 | "module": "commonjs",
6 | "outDir": "lib",
7 | "rootDir": "src",
8 | "strict": true,
9 | "target": "es2017",
10 | "sourceMap": true
11 | },
12 | "include": [
13 | "src/**/*"
14 | ]
15 | }
16 |
--------------------------------------------------------------------------------