tinyjukebox 0.47.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (154) hide show
  1. tinyjukebox/__init__.py +7 -0
  2. tinyjukebox/albumplayer/__init__.py +1 -0
  3. tinyjukebox/albumplayer/aalbumplayer.py +402 -0
  4. tinyjukebox/albumplayer/clock.py +39 -0
  5. tinyjukebox/albumplayer/dummyplayer.py +49 -0
  6. tinyjukebox/albumplayer/player_interface.py +97 -0
  7. tinyjukebox/albumplayer/radioplayer.py +391 -0
  8. tinyjukebox/albumplayer/simpleplayer.py +419 -0
  9. tinyjukebox/albumplayer/spotifyplayer.py +671 -0
  10. tinyjukebox/backup.py +176 -0
  11. tinyjukebox/backups.py +340 -0
  12. tinyjukebox/cli.py +1076 -0
  13. tinyjukebox/control.py +1386 -0
  14. tinyjukebox/core/__init__.py +1 -0
  15. tinyjukebox/core/config.py +100 -0
  16. tinyjukebox/core/logging/__init__.py +113 -0
  17. tinyjukebox/core/microservice.py +303 -0
  18. tinyjukebox/core/pubsub/__init__.py +15 -0
  19. tinyjukebox/core/pubsub/base.py +196 -0
  20. tinyjukebox/core/pubsub/localqueue.py +102 -0
  21. tinyjukebox/core/pubsub/statistics.py +57 -0
  22. tinyjukebox/core/py.typed +0 -0
  23. tinyjukebox/core/schema/__init__.py +5 -0
  24. tinyjukebox/core/schema/logger.py +40 -0
  25. tinyjukebox/core/schema/microservice.py +48 -0
  26. tinyjukebox/core/threads.py +39 -0
  27. tinyjukebox/core/ui/__init__.py +5 -0
  28. tinyjukebox/core/ui/cli.py +120 -0
  29. tinyjukebox/core/ui/tools.py +73 -0
  30. tinyjukebox/core/unexpected.py +46 -0
  31. tinyjukebox/data/__init__.py +0 -0
  32. tinyjukebox/data/activities.py +175 -0
  33. tinyjukebox/data/activity.py +138 -0
  34. tinyjukebox/data/common.py +91 -0
  35. tinyjukebox/data/degraded.py +39 -0
  36. tinyjukebox/data/jsondata.py +218 -0
  37. tinyjukebox/data/sanitycheck.py +71 -0
  38. tinyjukebox/data/tag.py +98 -0
  39. tinyjukebox/data/tags.py +160 -0
  40. tinyjukebox/data/target.py +568 -0
  41. tinyjukebox/data/targetalbumtools.py +88 -0
  42. tinyjukebox/data/targets.py +256 -0
  43. tinyjukebox/data/volumelimits.py +68 -0
  44. tinyjukebox/data_folder.py +180 -0
  45. tinyjukebox/devices/__init__.py +1 -0
  46. tinyjukebox/devices/baseclasses/__init__.py +1 -0
  47. tinyjukebox/devices/baseclasses/adriver.py +115 -0
  48. tinyjukebox/devices/baseclasses/aevents.py +47 -0
  49. tinyjukebox/devices/baseclasses/gpiolevel.py +16 -0
  50. tinyjukebox/devices/bluetooth/__init__.py +1 -0
  51. tinyjukebox/devices/bluetooth/avrcp_input.py +118 -0
  52. tinyjukebox/devices/bluetooth/bluez.py +446 -0
  53. tinyjukebox/devices/bluetooth/link.py +396 -0
  54. tinyjukebox/devices/bluetooth/virtual.py +155 -0
  55. tinyjukebox/devices/drivermanager/__init__.py +1 -0
  56. tinyjukebox/devices/drivermanager/driverfactory.py +75 -0
  57. tinyjukebox/devices/drivermanager/drivermanager.py +151 -0
  58. tinyjukebox/devices/drivers/__init__.py +31 -0
  59. tinyjukebox/devices/drivers/bluetooth.py +257 -0
  60. tinyjukebox/devices/drivers/input.py +165 -0
  61. tinyjukebox/devices/drivers/rfid.py +297 -0
  62. tinyjukebox/devices/drivers/rgbled.py +215 -0
  63. tinyjukebox/devices/py.typed +0 -0
  64. tinyjukebox/devices/schema/__init__.py +1 -0
  65. tinyjukebox/devices/schema/adriver.py +33 -0
  66. tinyjukebox/devices/schema/bluetooth.py +31 -0
  67. tinyjukebox/devices/schema/drivermanager.py +41 -0
  68. tinyjukebox/devices/schema/input.py +23 -0
  69. tinyjukebox/devices/schema/rfid.py +44 -0
  70. tinyjukebox/devices/schema/rgbled.py +26 -0
  71. tinyjukebox/diagnostics.py +179 -0
  72. tinyjukebox/errors.py +91 -0
  73. tinyjukebox/headset.py +296 -0
  74. tinyjukebox/images.py +133 -0
  75. tinyjukebox/latency.py +43 -0
  76. tinyjukebox/library/__init__.py +2 -0
  77. tinyjukebox/library/diagnostics.py +183 -0
  78. tinyjukebox/library/journal.py +94 -0
  79. tinyjukebox/library/releases.py +348 -0
  80. tinyjukebox/library/schema.py +98 -0
  81. tinyjukebox/library/service.py +1115 -0
  82. tinyjukebox/library/statistics.py +288 -0
  83. tinyjukebox/library/store.py +1386 -0
  84. tinyjukebox/messages.py +202 -0
  85. tinyjukebox/metadata.py +133 -0
  86. tinyjukebox/py.typed +0 -0
  87. tinyjukebox/restore.py +391 -0
  88. tinyjukebox/rgbled.py +158 -0
  89. tinyjukebox/schema/__init__.py +1 -0
  90. tinyjukebox/schema/activities.py +27 -0
  91. tinyjukebox/schema/tags.py +54 -0
  92. tinyjukebox/schema/targets.py +83 -0
  93. tinyjukebox/schema/tinyjukebox.py +217 -0
  94. tinyjukebox/schema/volume.py +28 -0
  95. tinyjukebox/slots.py +234 -0
  96. tinyjukebox/spotify/__init__.py +1 -0
  97. tinyjukebox/spotify/account.py +647 -0
  98. tinyjukebox/spotify/engine.py +568 -0
  99. tinyjukebox/spotify/oembed.py +65 -0
  100. tinyjukebox/spotify/soloist.py +198 -0
  101. tinyjukebox/spotify/sound.py +316 -0
  102. tinyjukebox/stm/__init__.py +0 -0
  103. tinyjukebox/stm/base.py +174 -0
  104. tinyjukebox/stm/playradio.py +237 -0
  105. tinyjukebox/stm/playspotify.py +418 -0
  106. tinyjukebox/stm/stmoperation.py +769 -0
  107. tinyjukebox/stm/stmplayalbum.py +655 -0
  108. tinyjukebox/stm/stmvolume.py +221 -0
  109. tinyjukebox/sync/__init__.py +42 -0
  110. tinyjukebox/sync/box.py +486 -0
  111. tinyjukebox/sync/client.py +189 -0
  112. tinyjukebox/sync/data.py +489 -0
  113. tinyjukebox/sync/files.py +447 -0
  114. tinyjukebox/sync/handshake.py +42 -0
  115. tinyjukebox/sync/link.py +379 -0
  116. tinyjukebox/sync/manifest.py +162 -0
  117. tinyjukebox/sync/util.py +137 -0
  118. tinyjukebox/tinyjukebox.py +680 -0
  119. tinyjukebox/tools/__init__.py +1 -0
  120. tinyjukebox/tools/backup.py +173 -0
  121. tinyjukebox/tools/fill_library.py +120 -0
  122. tinyjukebox/tools/import_cards.py +274 -0
  123. tinyjukebox/tools/import_covers.py +138 -0
  124. tinyjukebox/tools/migrate_box01.py +151 -0
  125. tinyjukebox/volumemanager.py +355 -0
  126. tinyjukebox/web/__init__.py +1 -0
  127. tinyjukebox/web/auth.py +373 -0
  128. tinyjukebox/web/certificates.py +111 -0
  129. tinyjukebox/web/logbuffer.py +62 -0
  130. tinyjukebox/web/server.py +1237 -0
  131. tinyjukebox/web/uploads.py +262 -0
  132. tinyjukebox/web/users.py +106 -0
  133. tinyjukebox/web/web/app.js +3050 -0
  134. tinyjukebox/web/web/favicon.svg +6 -0
  135. tinyjukebox/web/web/help/de/admin.html +714 -0
  136. tinyjukebox/web/web/help/de/manual.html +1147 -0
  137. tinyjukebox/web/web/help/de/quick-guide.html +79 -0
  138. tinyjukebox/web/web/help/en/admin.html +701 -0
  139. tinyjukebox/web/web/help/en/manual.html +1126 -0
  140. tinyjukebox/web/web/help/en/quick-guide.html +79 -0
  141. tinyjukebox/web/web/help/help.css +25 -0
  142. tinyjukebox/web/web/help/images/box-2026.jpg +0 -0
  143. tinyjukebox/web/web/help/images/box-back.jpg +0 -0
  144. tinyjukebox/web/web/help/images/lid-top.jpg +0 -0
  145. tinyjukebox/web/web/help/images/logo-mark.svg +38 -0
  146. tinyjukebox/web/web/index.html +867 -0
  147. tinyjukebox/web/web/style.css +412 -0
  148. tinyjukebox/web/web/texts/de.json +892 -0
  149. tinyjukebox/web/web/texts/en.json +892 -0
  150. tinyjukebox-0.47.0.dist-info/METADATA +236 -0
  151. tinyjukebox-0.47.0.dist-info/RECORD +154 -0
  152. tinyjukebox-0.47.0.dist-info/WHEEL +4 -0
  153. tinyjukebox-0.47.0.dist-info/entry_points.txt +9 -0
  154. tinyjukebox-0.47.0.dist-info/licenses/LICENSE.txt +21 -0
@@ -0,0 +1,701 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1">
6
+ <meta name="color-scheme" content="light dark">
7
+ <title>Tiny Jukebox – administration – Tiny Jukebox</title>
8
+ <link rel="icon" href="../../favicon.svg" type="image/svg+xml">
9
+ <link rel="stylesheet" href="../../style.css">
10
+ <link rel="stylesheet" href="../help.css">
11
+ </head>
12
+ <body class="help">
13
+ <!-- made by scripts/help/build.py from docs/user/en/admin.md - not to be changed by hand -->
14
+ <header class="topbar">
15
+ <a class="brand" href="../../"><svg class="brand-logo" viewBox="0 0 64 64" aria-hidden="true"><circle class="lid" cx="32" cy="32" r="29"/><circle class="window" cx="31" cy="41" r="10.5"/><circle class="brand-led" cx="13.29" cy="28.7" r="2.8"/><circle class="key" cx="17.45" cy="19.79" r="4.2"/><circle class="key" cx="25.5" cy="14.15" r="4.2"/><circle class="key key-yellow" cx="35.3" cy="13.29" r="4.2"/><circle class="key key-yellow" cx="44.21" cy="17.45" r="4.2"/></svg>Tiny Jukebox</a>
16
+ <span class="muted small">Help</span>
17
+ <nav class="tabs help-tabs"><a href="quick-guide.html">Quick guide</a><a href="manual.html">Manual</a><a href="admin.html" class=active aria-current=page>Administration</a></nav>
18
+ <div class="user"><a href="../de/admin.html" hreflang="de" lang="de">Deutsch</a>
19
+ <a class="button" href="../../">Back to the page</a></div>
20
+ </header>
21
+ <main class="help-text">
22
+ <h1 id="tiny-jukebox--administration">Tiny Jukebox – administration</h1>
23
+ <p>For the person who sets up and runs the boxes and the library at home: with a terminal, a NAS or a PC, and a
24
+ browser. What to do, in steps, and what happens then. How the box is operated and what the web page offers is in the
25
+ <a href="manual.html">manual</a>; this document points to it instead of repeating it. Every detail – every command, every option,
26
+ every file – is in the developer documents (<a href="https://tgd1975.github.io/tinyjukebox/reference/operations/"><code>docs/developer/</code></a>, in English).</p>
27
+ <p>Contents:</p>
28
+ <ol>
29
+ <li><a href="#1-overview">Overview</a></li>
30
+ <li><a href="#2-setting-up-a-box">Setting up a box</a></li>
31
+ <li><a href="#3-the-library">The library</a></li>
32
+ <li><a href="#4-updates">Updates</a></li>
33
+ <li><a href="#5-users-and-access">Users and access</a></li>
34
+ <li><a href="#6-data-and-backups">Data and backups</a></li>
35
+ <li><a href="#7-logs-and-diagnostics">Logs and diagnostics</a></li>
36
+ <li><a href="#8-configuration">Configuration</a></li>
37
+ <li><a href="#9-if-something-does-not-work">If something does not work</a></li>
38
+ </ol>
39
+ <hr />
40
+ <h2 id="1-overview"><span id="s1"></span>1. Overview</h2>
41
+ <h3 id="11-what-runs-where"><span id="s1-1"></span>1.1 What runs where</h3>
42
+ <table>
43
+ <thead>
44
+ <tr>
45
+ <th>What</th>
46
+ <th>Where it runs</th>
47
+ <th>Its page</th>
48
+ <th>Its data</th>
49
+ </tr>
50
+ </thead>
51
+ <tbody>
52
+ <tr>
53
+ <td>Box</td>
54
+ <td>a Raspberry Pi in the wooden case</td>
55
+ <td><code>https://&lt;name of the box&gt;.local</code>, e.g. <code>https://tinyjukebox.local</code></td>
56
+ <td><code>/srv/tinyjukebox/</code> on its SD card</td>
57
+ </tr>
58
+ <tr>
59
+ <td>Library on the NAS</td>
60
+ <td>the Synology package <code>tinyjukebox-library</code></td>
61
+ <td><code>https://&lt;nas&gt;:8866</code></td>
62
+ <td><code>/var/packages/tinyjukebox-library/var/</code> and the shared folder <code>tinyjukebox</code></td>
63
+ </tr>
64
+ <tr>
65
+ <td>Library in Docker or on a PC</td>
66
+ <td>the image <code>ghcr.io/tgd1975/tinyjukebox</code>, or <code>tinyjukebox-library --data DIR</code></td>
67
+ <td><code>https://&lt;computer&gt;:8866</code></td>
68
+ <td>the volume <code>/data</code>, or the folder <code>DIR</code></td>
69
+ </tr>
70
+ <tr>
71
+ <td>App</td>
72
+ <td>an Android phone: a phone as a box, or the page of the library</td>
73
+ <td>–</td>
74
+ <td>on the phone (<a href="manual.html#137-the-app-a-phone-as-a-box">manual</a>, section 13.7)</td>
75
+ </tr>
76
+ </tbody>
77
+ </table>
78
+ <p>A box works alone. With a library the boxes share albums, tags, stations and covers, and the library keeps the
79
+ progress of every box (<a href="manual.html#13-library">manual</a>, section 13). A box without a library fetches new versions of
80
+ its software from GitHub; a box with a library fetches them from the library.</p>
81
+ <h3 id="12-roles"><span id="s1-2"></span>1.2 Roles</h3>
82
+ <ul>
83
+ <li><code>admin</code> may do everything: albums, tags, stations, users, backups, versions.</li>
84
+ <li><code>user</code> may operate the box – status, player, volume, buttons – and change the own password; on the library also make
85
+ a tag known by scanning it.</li>
86
+ </ul>
87
+ <p>A box and the library each have their own users. Users and passwords on the page:
88
+ <a href="manual.html#11-users-and-passwords">manual</a>, section 11.</p>
89
+ <h3 id="13-the-files-of-a-box"><span id="s1-3"></span>1.3 The files of a box</h3>
90
+ <table>
91
+ <thead>
92
+ <tr>
93
+ <th>Folder</th>
94
+ <th>Content</th>
95
+ </tr>
96
+ </thead>
97
+ <tbody>
98
+ <tr>
99
+ <td><code>/srv/tinyjukebox/albums/</code></td>
100
+ <td>one folder per album: MP3 files and <code>playlist.m3u</code></td>
101
+ </tr>
102
+ <tr>
103
+ <td><code>/srv/tinyjukebox/json/</code></td>
104
+ <td>tags, albums, stations, progress, volume limits; <code>images/</code>: the covers</td>
105
+ </tr>
106
+ <tr>
107
+ <td><code>/srv/tinyjukebox/ssl/</code></td>
108
+ <td>certificate of the page and <code>users.yaml</code>, the users</td>
109
+ </tr>
110
+ <tr>
111
+ <td><code>/srv/tinyjukebox/log/</code></td>
112
+ <td><code>tinyjukebox.log</code>, the log of the box</td>
113
+ </tr>
114
+ <tr>
115
+ <td><code>/srv/tinyjukebox/slots/</code>, <code>current</code></td>
116
+ <td>the versions of the box software and the one that runs</td>
117
+ </tr>
118
+ <tr>
119
+ <td><code>/srv/tinyjukebox/state/</code></td>
120
+ <td>which version runs and why; <code>history.log</code>, one line per switch</td>
121
+ </tr>
122
+ <tr>
123
+ <td><code>/srv/tinyjukebox/identity/</code>, <code>sync/</code></td>
124
+ <td>the key of the box and the address of its library; what it exchanges with the library</td>
125
+ </tr>
126
+ <tr>
127
+ <td><code>/srv/tinyjukebox/spotify/</code></td>
128
+ <td>key, player and login of Spotify</td>
129
+ </tr>
130
+ <tr>
131
+ <td><code>/srv/tinyjukebox/config/</code></td>
132
+ <td><code>tinyjukebox.yaml</code>, if there is one (section 8)</td>
133
+ </tr>
134
+ </tbody>
135
+ </table>
136
+ <p>All of it belongs to the user of the box, <code>pi</code> on our box. The complete list:
137
+ <a href="https://tgd1975.github.io/tinyjukebox/hardware/box/#6-file-system-layout">box.md</a>, section 6.</p>
138
+ <hr />
139
+ <h2 id="2-setting-up-a-box"><span id="s2"></span>2. Setting up a box</h2>
140
+ <h3 id="21-what-is-needed"><span id="s2-1"></span>2.1 What is needed</h3>
141
+ <ul>
142
+ <li>a Raspberry Pi with the hardware of the box (<a href="https://tgd1975.github.io/tinyjukebox/hardware/box/#1-hardware">box.md</a>, section 1) – a box that is
143
+ not wired yet can be installed as well; its page answers, and the log names what is missing</li>
144
+ <li>an SD card and the Raspberry Pi Imager on the PC</li>
145
+ <li>a WLAN with internet: the installer fetches the packages of the operating system</li>
146
+ <li>the password the user <code>admin</code> of the page of the box shall have, at least 8 characters</li>
147
+ <li>with a library: its bootstrap password, set when the library was installed (section 3)</li>
148
+ </ul>
149
+ <h3 id="22-writing-the-card"><span id="s2-2"></span>2.2 Writing the card</h3>
150
+ <ol>
151
+ <li>In the Raspberry Pi Imager choose "Raspberry Pi OS Lite (64-bit)".</li>
152
+ <li>In the settings of the Imager set the hostname (e.g. <code>kitchen</code> – the page is then <code>https://kitchen.local</code>), the
153
+ user, the WLAN with its country, the time zone and SSH; the Imager offers "public-key authentication only".</li>
154
+ <li>Write the card, put it into the box and switch the box on.</li>
155
+ <li>Log in from the PC: <code>ssh &lt;user&gt;@&lt;hostname&gt;.local</code>.</li>
156
+ </ol>
157
+ <p>The installer never touches what the Imager set: hostname, user, WLAN, time zone, SSH.</p>
158
+ <h3 id="23-the-installer"><span id="s2-3"></span>2.3 The installer</h3>
159
+ <p>A box that works alone gets the installer from GitHub:</p>
160
+ <pre><code class="language-bash">curl -fsSL https://github.com/tgd1975/tinyjukebox/releases/latest/download/install.sh | sudo bash
161
+ </code></pre>
162
+ <p>A box for a library gets its line from the page of the library: tab "Boxes", section "Add a box", "Copy". The line
163
+ names the library and the key of its certificate, so that the box trusts exactly this library.</p>
164
+ <p>What happens:</p>
165
+ <ul>
166
+ <li><strong>All questions come first:</strong> the password of the user <code>admin</code> of the page and, with a library, the bootstrap
167
+ password. They are read from the terminal, never from the command line.</li>
168
+ <li>The installer checks that it runs on Raspberry Pi OS Lite (64-bit), Debian 13. On anything else it stops before
169
+ it changes something and says what it found.</li>
170
+ <li>It sets up the system, installs the box software into a slot and prints the address of the page. It restarts the
171
+ box once. On a Pi 3 it takes a few minutes; nothing is compiled.</li>
172
+ <li>A box for a library registers at its first start and appears in the tab "Boxes" of the library by itself.</li>
173
+ <li>What it printed is kept in <code>/var/log/tinyjukebox-install.log</code>, also what happened after the restart.</li>
174
+ </ul>
175
+ <p><strong>Running it again</strong> is safe: it changes nothing that is right already, and it never touches albums, tags, progress,
176
+ users or the link to a library. It is also the way to bring the system of a box up to date (section 4.4). There is
177
+ no uninstaller: a Pi is freed by writing its card anew.</p>
178
+ <p>All options of the installer: <a href="https://tgd1975.github.io/tinyjukebox/reference/deployment/#51-with-the-installer">deployment.md</a>, section 5.1.</p>
179
+ <h3 id="24-after-the-installation"><span id="s2-4"></span>2.4 After the installation</h3>
180
+ <ul>
181
+ <li>The first start should happen with WLAN: the box has no clock, and the certificate of the page is created then.</li>
182
+ <li>Open the page and log in as <code>admin</code>. The browser warns about the certificate the first time (section 5.4).</li>
183
+ <li>Choose the language under the login, "Deutsch / English".</li>
184
+ <li>Place a tag: the LED turns yellow, and the tab "Now" offers to link it (<a href="manual.html#72-linking-a-tag">manual</a>,
185
+ section 7.2).</li>
186
+ <li>If there are several boxes, give the box a name: tab "System", section "Library", "Rename".</li>
187
+ </ul>
188
+ <p>For a box that was set up anew, the <a href="https://tgd1975.github.io/tinyjukebox/reference/deployment/#8-acceptance-checklist">acceptance checklist</a> goes
189
+ through start, buttons, LED, tags and headset one by one.</p>
190
+ <h3 id="25-with-the-playbook"><span id="s2-5"></span>2.5 With the playbook</h3>
191
+ <p>Our own box is set up from the PC with an Ansible playbook, which runs the installer and also writes the config of
192
+ the box and its users. That is the way for a developer who keeps the box in the repository:
193
+ <a href="https://tgd1975.github.io/tinyjukebox/reference/deployment/#52-with-the-playbook">deployment.md</a>, section 5.2.</p>
194
+ <hr />
195
+ <h2 id="3-the-library"><span id="s3"></span>3. The library</h2>
196
+ <h3 id="31-where-it-runs"><span id="s3-1"></span>3.1 Where it runs</h3>
197
+ <table>
198
+ <thead>
199
+ <tr>
200
+ <th>Where</th>
201
+ <th>How</th>
202
+ <th>Updated</th>
203
+ </tr>
204
+ </thead>
205
+ <tbody>
206
+ <tr>
207
+ <td>Synology NAS</td>
208
+ <td>the package <code>tinyjukebox-library</code>, installed in the Package Center</td>
209
+ <td>by hand, with a newer package (section 4.3)</td>
210
+ </tr>
211
+ <tr>
212
+ <td>Docker</td>
213
+ <td>the image <code>ghcr.io/tgd1975/tinyjukebox</code> (<code>linux/amd64</code>, <code>linux/arm64</code>)</td>
214
+ <td>by pulling a newer image</td>
215
+ </tr>
216
+ <tr>
217
+ <td>PC</td>
218
+ <td><code>pip install tinyjukebox</code>, then <code>tinyjukebox-library --data DIR</code></td>
219
+ <td>with <code>pip install --upgrade tinyjukebox</code></td>
220
+ </tr>
221
+ </tbody>
222
+ </table>
223
+ <p>The package is built for one platform, <code>rtd1296</code> – the DS418j and NAS with the same processor. Another NAS needs
224
+ another build, or Docker.</p>
225
+ <h3 id="32-on-the-nas"><span id="s3-2"></span>3.2 On the NAS</h3>
226
+ <ol>
227
+ <li><strong>Before:</strong> install the Python 3.12 of SynoCommunity on the NAS (the package <code>python312</code>). Choose a bootstrap
228
+ password of at least 16 characters, e.g. with <code>openssl rand -hex 24</code>. Every box proves it once, the first time it
229
+ connects.</li>
230
+ <li><strong>Fetch the package</strong> (<code>tinyjukebox-library-&lt;version&gt;-&lt;build&gt;-rtd1296.spk</code>) from the newest release on GitHub. With
231
+ a clone of the repository on the PC, <code>./fetch_release.sh</code> fetches it into <code>dist/</code> and checks it.</li>
232
+ <li><strong>Install it:</strong> Package Center of DSM, "Manual Install", choose the file, confirm the warning about packages of
233
+ third parties. The dialog asks for the password of the user <code>admin</code> of the page (at least 8 characters) and for
234
+ the bootstrap password.</li>
235
+ <li><strong>Check:</strong> the Package Center shows the package as running, and <code>https://&lt;nas&gt;:8866</code> opens the page. Log in as
236
+ <code>admin</code>. If the start failed, the reason is in <code>var/server.log</code> (section 7.2).</li>
237
+ <li><strong>Users:</strong> the library has the user <code>admin</code> only. Add the others on its page, tab "System", section "Users".</li>
238
+ </ol>
239
+ <p>The package runs as a user of its own, <code>tinyjukebox-library</code>. DSM creates the shared folder <code>tinyjukebox</code> at the first
240
+ start, with <code>albums/</code>, <code>images/</code> and <code>json/</code> in it; albums can also be put there with SMB or File Station, and Hyper
241
+ Backup includes the folder. Certificate, users and config live in
242
+ <code>/var/packages/tinyjukebox-library/var/</code>, which an update keeps and which DSM never removes – also not when the
243
+ package is removed. To start from nothing: <a href="https://tgd1975.github.io/tinyjukebox/reference/library/#37-first-installation-on-the-nas">library.md</a>,
244
+ section 3.7.</p>
245
+ <h3 id="33-in-docker"><span id="s3-3"></span>3.3 In Docker</h3>
246
+ <p>Two passwords as files, then compose starts a library and a box without hardware to try:</p>
247
+ <pre><code class="language-bash">cd deploy/docker &amp;&amp; openssl rand -hex 12 &gt; admin-password &amp;&amp; openssl rand -hex 24 &gt; bootstrap-password
248
+ docker compose up -d # https://localhost:8866/ and https://localhost:8443/, user admin, the password in admin-password
249
+ </code></pre>
250
+ <p>The library alone:</p>
251
+ <pre><code class="language-bash">docker run -d --name library --restart unless-stopped -p 8866:8866 \
252
+ -v library:/data -v /path/to/albums:/data/albums ghcr.io/tgd1975/tinyjukebox
253
+ </code></pre>
254
+ <ul>
255
+ <li>Everything that must survive lies below <code>/data</code>: one volume, and if wanted the albums as a folder of the host. A
256
+ mounted folder must be writable for the user of the image (uid 1000).</li>
257
+ <li>Without <code>TINYJUKEBOX_ADMIN_PASSWORD</code> the password of <code>admin</code> is generated and printed once: <code>docker logs library</code>.</li>
258
+ <li>The bootstrap password comes from <code>TINYJUKEBOX_BOOTSTRAP_PASSWORD</code>, or it is set in the tab "Boxes".</li>
259
+ <li>Instead of the passwords themselves, <code>TINYJUKEBOX_ADMIN_PASSWORD_FILE</code> and <code>TINYJUKEBOX_BOOTSTRAP_PASSWORD_FILE</code>
260
+ name a file that holds them; a variable can be read with <code>docker inspect</code>.</li>
261
+ <li>A box joins with the line of the tab "Boxes". Its address must be the one of the host, not the name of the
262
+ container.</li>
263
+ </ul>
264
+ <p>More: <a href="https://tgd1975.github.io/tinyjukebox/reference/library/#39-the-library-in-docker-and-with-one-folder">library.md</a>, section 3.9.</p>
265
+ <h3 id="34-on-a-pc"><span id="s3-4"></span>3.4 On a PC</h3>
266
+ <pre><code class="language-bash">pip install tinyjukebox
267
+ tinyjukebox-library --data ~/library # https://localhost:8866/
268
+ </code></pre>
269
+ <p>Everything lies below the folder: <code>data/</code>, <code>albums/</code>, <code>images/</code>, <code>ssl/</code>, <code>log/</code>, <code>backups/</code>. At the first start it
270
+ asks for the password of <code>admin</code> on the terminal. A computer that is switched off is no library for the boxes: they
271
+ play on with what they have and deliver their changes later.</p>
272
+ <h3 id="35-filling-it-with-the-data-of-a-box"><span id="s3-5"></span>3.5 Filling it with the data of a box</h3>
273
+ <p>The library starts empty. If a box has albums and tags already, a command on the PC brings them over. It keeps the
274
+ ids, so that box and library agree from the start, and it can be repeated: what is there already is skipped.</p>
275
+ <pre><code class="language-bash">rsync -a pi@tinyjukebox.local:/srv/tinyjukebox/json/ ~/box-copy/json/
276
+ rsync -a pi@tinyjukebox.local:/srv/tinyjukebox/albums/ ~/box-copy/albums/
277
+ tinyjukebox-fill-library https://&lt;nas&gt;:8866 --user admin \
278
+ --json ~/box-copy/json --albums ~/box-copy/albums --images ~/box-copy/json/images
279
+ </code></pre>
280
+ <p>It asks for the password and shows the fingerprint of the certificate of the library for confirmation (section 5.4).
281
+ In a clone of the repository the command is <code>uv run tinyjukebox-fill-library …</code>. The progress comes from the box
282
+ itself with its first synchronization. A box that is simply connected to the library brings its data as well
283
+ (<a href="manual.html#132-connecting-a-box-to-the-library">manual</a>, section 13.2); this command is for many albums at once.</p>
284
+ <h3 id="36-connecting-the-boxes"><span id="s3-6"></span>3.6 Connecting the boxes</h3>
285
+ <ul>
286
+ <li><strong>A box that runs already:</strong> on its page, tab "System", section "Library": the address and the bootstrap password
287
+ (<a href="manual.html#132-connecting-a-box-to-the-library">manual</a>, section 13.2).</li>
288
+ <li><strong>A new box:</strong> the line of the tab "Boxes", section "Add a box" (section 2.3).</li>
289
+ <li><strong>A box that was set up again</strong> is a new box. On the page of the library, tab "Boxes", it takes over the progress
290
+ and settings of the old one.</li>
291
+ </ul>
292
+ <h3 id="37-new-versions-for-the-boxes"><span id="s3-7"></span>3.7 New versions for the boxes</h3>
293
+ <p>The library fetches the versions of the box software from the releases on GitHub and hands them to its boxes. For
294
+ that it needs access to the releases:</p>
295
+ <ul>
296
+ <li><strong>The repository is public:</strong> an empty file <code>var/github-token</code> on the NAS is enough, owned by the user
297
+ <code>tinyjukebox-library</code>; then stop and start the package.</li>
298
+ <li><strong>The repository is private:</strong> create a fine-grained token on GitHub for this one repository with the right
299
+ "Contents: Read-only", and enter it on the page of the library, tab "Versions", section "Access to the releases".
300
+ The library checks it before it keeps it and looks for a release at once.</li>
301
+ </ul>
302
+ <p>The Docker image and <code>tinyjukebox-library --data</code> ask the releases of the project without a token. Which version a
303
+ box gets and how it is tried: section 4.1.</p>
304
+ <hr />
305
+ <h2 id="4-updates"><span id="s4"></span>4. Updates</h2>
306
+ <h3 id="41-the-box-software"><span id="s4-1"></span>4.1 The box software</h3>
307
+ <p>A box installs new versions by itself: with a library from the library, without one from GitHub. A new version starts
308
+ the next time the box is switched on, on probation. If it does not work – it does not start, or it fails its first
309
+ seconds – the box starts the version before after a few seconds by itself. A version stays on probation until a tag
310
+ was placed and an album played because of it.</p>
311
+ <ul>
312
+ <li><strong>Without a library</strong> the box looks once a day for a new release and installs it after a waiting time of three days;
313
+ a correction in that time replaces it before any box got it.</li>
314
+ <li><strong>With a library</strong> a box gets a new version at once. In the tab "Versions" of the library every version has a state:
315
+ <code>use</code> (boxes install it by themselves), <code>manual</code> (by hand only), <code>dontuse</code> (every box leaves it at once).</li>
316
+ <li><strong>The update mode</strong> of a box – "automatic", "by hand only" ("ask" without a library) or "off" – is set on its page,
317
+ tab "System", section "Version" (<a href="manual.html#134-version-of-the-box">manual</a>, section 13.4).</li>
318
+ </ul>
319
+ <p>On the box the same is a command. It runs as the user of the box, never with <code>sudo</code>:</p>
320
+ <pre><code class="language-bash">tinyjukebox-slot status # the versions on the box, the one that runs, the mode, the last switches
321
+ tinyjukebox-slot check # what the library offers - without a library: GitHub
322
+ tinyjukebox-slot update --now # the newest permitted version, at once
323
+ tinyjukebox-slot update 0.45.0 # exactly this version
324
+ tinyjukebox-slot mode manual # automatic, manual or off
325
+ </code></pre>
326
+ <p>Every call: <a href="https://tgd1975.github.io/tinyjukebox/reference/library/#68-the-command-tinyjukebox-slot">library.md</a>, section 6.8.</p>
327
+ <h3 id="42-going-back-to-the-version-before"><span id="s4-2"></span>4.2 Going back to the version before</h3>
328
+ <p>A step back takes effect at once, also while something is playing. No box installs the version that was left by
329
+ itself any more.</p>
330
+ <table>
331
+ <thead>
332
+ <tr>
333
+ <th>Way</th>
334
+ <th>For</th>
335
+ </tr>
336
+ </thead>
337
+ <tbody>
338
+ <tr>
339
+ <td>page of the box, tab "System", "Back to the previous version"</td>
340
+ <td>this box</td>
341
+ </tr>
342
+ <tr>
343
+ <td><code>tinyjukebox-slot revert</code> on the box</td>
344
+ <td>this box</td>
345
+ </tr>
346
+ <tr>
347
+ <td>an empty file <code>tinyjukebox-revert</code> on the boot partition of the SD card (<code>bootfs</code> on the PC)</td>
348
+ <td>this box, without network: the next start goes back and writes <code>tinyjukebox-ergebnis.txt</code> in its place</td>
349
+ </tr>
350
+ <tr>
351
+ <td>page of the library, tab "Versions": the version to <code>dontuse</code></td>
352
+ <td>all boxes</td>
353
+ </tr>
354
+ </tbody>
355
+ </table>
356
+ <p><code>revert</code> switches to the other slot, whatever it holds. After a failed probation that may be the version that failed:
357
+ look first with <code>tinyjukebox-slot status</code>. If no version starts any more, the box is in emergency mode
358
+ (<a href="manual.html#134-version-of-the-box">manual</a>, section 13.4;
359
+ <a href="https://tgd1975.github.io/tinyjukebox/reference/library/#610-fallback-slot-and-recovery-mode">library.md</a>, section 6.10).</p>
360
+ <h3 id="43-the-library"><span id="s4-3"></span>4.3 The library</h3>
361
+ <p>The library never updates itself.</p>
362
+ <ul>
363
+ <li><strong>On the NAS:</strong> install the newer package the same way, Package Center, "Manual Install" – without the dialog; the
364
+ data stays. From a clone of the repository on the PC, <code>./update_library.sh &lt;nas&gt;</code> does it: it fetches the package of
365
+ the newest release and asks for user and password of DSM, which it does not store – or takes NAS, user and
366
+ password from the vault of the playbook (<a href="https://tgd1975.github.io/tinyjukebox/reference/library/#37-first-installation-on-the-nas">library.md</a>,
367
+ section 3.7).</li>
368
+ <li><strong>In Docker:</strong> its page shows that a newer version exists. Pull the newer image and start the container again;
369
+ with compose <code>docker compose pull</code>, then <code>docker compose up -d</code>.</li>
370
+ <li><strong>On a PC:</strong> <code>pip install --upgrade tinyjukebox</code>, then start the library again.</li>
371
+ </ul>
372
+ <p>A library that is older than the version of a box makes the box stop: the LED changes between red, white, magenta and
373
+ yellow, and the box plays nothing. Then update the library first.</p>
374
+ <h3 id="44-the-operating-system-of-the-box"><span id="s4-4"></span>4.4 The operating system of the box</h3>
375
+ <p>The box never updates its operating system by itself. By hand, now and then:</p>
376
+ <pre><code class="language-bash">sudo apt update &amp;&amp; sudo apt full-upgrade
377
+ </code></pre>
378
+ <p>After an upgrade of Python, ALSA or BlueZ, run the installer line again (section 2.3) – on a box of the playbook
379
+ <code>./update_box.sh</code> – and check sound, buttons and headset. A version that needs a newer setup of the system says so on
380
+ the page of the box: then the installer has to run again as well.</p>
381
+ <hr />
382
+ <h2 id="5-users-and-access"><span id="s5"></span>5. Users and access</h2>
383
+ <h3 id="51-users-from-the-command-line"><span id="s5-1"></span>5.1 Users from the command line</h3>
384
+ <p>On the page an admin adds and removes users and sets passwords (<a href="manual.html#11-users-and-passwords">manual</a>,
385
+ section 11). On the box, as the user of the box:</p>
386
+ <pre><code class="language-bash">tinyjukebox-users -f /srv/tinyjukebox/ssl/users.yaml list
387
+ tinyjukebox-users -f /srv/tinyjukebox/ssl/users.yaml add NAME --role admin
388
+ tinyjukebox-users -f /srv/tinyjukebox/ssl/users.yaml passwd NAME
389
+ tinyjukebox-users -f /srv/tinyjukebox/ssl/users.yaml role NAME admin
390
+ tinyjukebox-users -f /srv/tinyjukebox/ssl/users.yaml remove NAME
391
+ </code></pre>
392
+ <ul>
393
+ <li>Only here can a role be changed. The command removes neither the last admin nor makes them a <code>user</code>.</li>
394
+ <li>A change takes effect at once, without a restart. A new password ends the other sessions of that user.</li>
395
+ <li>For a library on a PC the file is <code>ssl/users.yaml</code> in its folder. In Docker the image runs the command, with the
396
+ volume of the library: <code>docker run --rm -v library:/data ghcr.io/tgd1975/tinyjukebox tinyjukebox-users -f
397
+ /data/ssl/users.yaml list</code>.</li>
398
+ <li>The package on the NAS has no command <code>tinyjukebox-users</code>: the call with the Python of the package is in
399
+ <a href="https://tgd1975.github.io/tinyjukebox/reference/operations/#4-users-of-the-web-page">operations.md</a>, section 4.</li>
400
+ </ul>
401
+ <h3 id="52-a-forgotten-password"><span id="s5-2"></span>5.2 A forgotten password</h3>
402
+ <ol>
403
+ <li>Another admin sets a new password on the page, tab "System", section "Users".</li>
404
+ <li>If no admin knows a password any more: log in on the box with SSH.</li>
405
+ <li><code>tinyjukebox-users -f /srv/tinyjukebox/ssl/users.yaml passwd admin</code> – it asks for the new password twice.</li>
406
+ <li>Log in on the page with it.</li>
407
+ </ol>
408
+ <h3 id="53-ssh"><span id="s5-3"></span>5.3 SSH</h3>
409
+ <p>The box is reached with <code>ssh &lt;user&gt;@&lt;hostname&gt;.local</code>, as the Imager set it up. If the name is not found, the address
410
+ of the box in the router helps. A card that was written anew has a new key: if the PC still knows the old one,
411
+ SSH refuses until the old entry is removed with <code>ssh-keygen -R &lt;hostname&gt;.local</code>.</p>
412
+ <h3 id="54-the-certificate-of-the-page"><span id="s5-4"></span>5.4 The certificate of the page</h3>
413
+ <p>Box and library make their own certificate, at their first start. The browser warns about it the first time.</p>
414
+ <ul>
415
+ <li>Compare the fingerprint the browser shows with the one in the log: the box writes it when the page starts
416
+ (<code>rest api listening on … fingerprint</code>), the library into its log as well.</li>
417
+ <li>Or import the certificate of the box as trusted: <code>/srv/tinyjukebox/ssl/tinyjukebox.crt</code>.</li>
418
+ <li>The commands on the PC, <code>tinyjukebox-backup</code> and <code>tinyjukebox-fill-library</code>, show the fingerprint too and ask
419
+ before they go on.</li>
420
+ </ul>
421
+ <hr />
422
+ <h2 id="6-data-and-backups"><span id="s6"></span>6. Data and backups</h2>
423
+ <h3 id="61-what-a-backup-holds"><span id="s6-1"></span>6.1 What a backup holds</h3>
424
+ <p>A backup is one file with the data of a box or of the library, made while it runs:</p>
425
+ <ul>
426
+ <li>a box: tags, albums, stations and entries of Spotify, progress, volume limits and the covers</li>
427
+ <li>the library: the catalog, the progress and settings of every box, the statistics, the states of the versions and
428
+ the covers</li>
429
+ <li>with "MP3s" also the albums – the file is then as large as all albums together</li>
430
+ </ul>
431
+ <p>A box with a library needs no backup of its own: the library has everything, and a box that is set up again fetches it
432
+ from there.</p>
433
+ <h3 id="62-making-backups"><span id="s6-2"></span>6.2 Making backups</h3>
434
+ <table>
435
+ <thead>
436
+ <tr>
437
+ <th>Way</th>
438
+ <th>Box</th>
439
+ <th>Library</th>
440
+ </tr>
441
+ </thead>
442
+ <tbody>
443
+ <tr>
444
+ <td>page, tab "System", card "Backup"</td>
445
+ <td>"Download backup", "Download backup with MP3s"</td>
446
+ <td>the same</td>
447
+ </tr>
448
+ <tr>
449
+ <td>page, "Back up regularly"</td>
450
+ <td>a box without a library, into <code>/srv/tinyjukebox/backups</code></td>
451
+ <td>into the shared folder <code>tinyjukebox</code> on the NAS, which Hyper Backup includes</td>
452
+ </tr>
453
+ <tr>
454
+ <td>command on the PC</td>
455
+ <td><code>tinyjukebox-backup https://tinyjukebox.local --user admin [--albums] [FOLDER]</code></td>
456
+ <td><code>tinyjukebox-backup https://&lt;nas&gt;:8866 --user admin [--albums] [FOLDER]</code></td>
457
+ </tr>
458
+ </tbody>
459
+ </table>
460
+ <p>Two schedules, one without and one with the albums, with their folder and how many are kept:
461
+ <a href="manual.html#112-back-up-regularly">manual</a>, section 11.2. The backups of a box lie on its SD card: against a broken card
462
+ only a backup helps that was fetched from it.</p>
463
+ <h3 id="63-putting-a-backup-back"><span id="s6-3"></span>6.3 Putting a backup back</h3>
464
+ <p>On the page, tab "System", card "Backup", "Put a backup back" – or <code>tinyjukebox-backup … --restore FILE</code> on the PC.
465
+ The page asks once, then the box or the library starts again with the data of the backup
466
+ (<a href="manual.html#113-putting-a-backup-back">manual</a>, section 11.3).</p>
467
+ <ul>
468
+ <li>A backup without the albums leaves the albums folder alone. Albums the data names but whose folder is missing are
469
+ listed after the restore.</li>
470
+ <li>On a box with a library the library wins at the next synchronization. A restore is meant for a box without a
471
+ library and for the library.</li>
472
+ <li>The library on another NAS, or by hand without the program:
473
+ <a href="https://tgd1975.github.io/tinyjukebox/reference/operations/#103-putting-a-backup-back">operations.md</a>, section 10.3.</li>
474
+ </ul>
475
+ <h3 id="64-what-no-backup-holds"><span id="s6-4"></span>6.4 What no backup holds</h3>
476
+ <ul>
477
+ <li>users, passwords, the certificate, tokens – in the library also <code>settings.json</code> with the bootstrap password</li>
478
+ <li>the key of the box and its link to the library</li>
479
+ <li>the key, the player and the login of Spotify: the key is pasted again, the box fetches the player again and is
480
+ connected again ("Connect")</li>
481
+ <li>the config file</li>
482
+ </ul>
483
+ <hr />
484
+ <h2 id="7-logs-and-diagnostics"><span id="s7"></span>7. Logs and diagnostics</h2>
485
+ <h3 id="71-the-logs-of-a-box"><span id="s7-1"></span>7.1 The logs of a box</h3>
486
+ <table>
487
+ <thead>
488
+ <tr>
489
+ <th>Log</th>
490
+ <th>Content</th>
491
+ </tr>
492
+ </thead>
493
+ <tbody>
494
+ <tr>
495
+ <td>page, tab "Log" (admin)</td>
496
+ <td>the last 5000 entries, live, with filters for level and text; "Save as file"</td>
497
+ </tr>
498
+ <tr>
499
+ <td><code>/srv/tinyjukebox/log/tinyjukebox.log</code> (+ <code>.1</code> … <code>.4</code>)</td>
500
+ <td>the complete log; it stays over a restart</td>
501
+ </tr>
502
+ <tr>
503
+ <td><code>journalctl -u tinyjukebox</code></td>
504
+ <td>warnings and errors, and what the start script says; gone after a restart</td>
505
+ </tr>
506
+ <tr>
507
+ <td><code>/srv/tinyjukebox/state/history.log</code></td>
508
+ <td>one line per switch of version: when, from, to, why, by whom</td>
509
+ </tr>
510
+ <tr>
511
+ <td><code>/var/log/tinyjukebox-install.log</code></td>
512
+ <td>what the installer did</td>
513
+ </tr>
514
+ </tbody>
515
+ </table>
516
+ <p>The service itself: <code>sudo systemctl status tinyjukebox</code>, <code>sudo systemctl restart tinyjukebox</code>. After a crash systemd
517
+ starts it again by itself.</p>
518
+ <h3 id="72-the-logs-of-the-library"><span id="s7-2"></span>7.2 The logs of the library</h3>
519
+ <table>
520
+ <thead>
521
+ <tr>
522
+ <th>Log</th>
523
+ <th>Content</th>
524
+ </tr>
525
+ </thead>
526
+ <tbody>
527
+ <tr>
528
+ <td>page of the library, tab "Log"</td>
529
+ <td>the log of the library, and that of every box: warnings, errors and events the boxes sent, with filters; "Save as file"</td>
530
+ </tr>
531
+ <tr>
532
+ <td>NAS: <code>/var/packages/tinyjukebox-library/var/library.log</code></td>
533
+ <td>the log of the library; at the start its fingerprint</td>
534
+ </tr>
535
+ <tr>
536
+ <td>NAS: <code>var/server.log</code></td>
537
+ <td>why a start failed</td>
538
+ </tr>
539
+ <tr>
540
+ <td>NAS: <code>/var/log/packages/tinyjukebox-library.log</code></td>
541
+ <td>what the scripts of the package printed</td>
542
+ </tr>
543
+ <tr>
544
+ <td>Docker: <code>docker logs library</code></td>
545
+ <td>the output of the library, the generated password of <code>admin</code></td>
546
+ </tr>
547
+ </tbody>
548
+ </table>
549
+ <p>The tab "Log" of the library helps when a box is not at hand: the boxes send their warnings and errors to the
550
+ library, without passwords, keys or tag UIDs. A box that cannot start reports that too; the tab "Boxes" then shows
551
+ "cannot start since …" (<a href="https://tgd1975.github.io/tinyjukebox/reference/library/#422-central-diagnostics">library.md</a>, section 4.22).</p>
552
+ <h3 id="73-more-detail-in-the-log"><span id="s7-3"></span>7.3 More detail in the log</h3>
553
+ <p>The box logs at the level INFO. For a search, set it to DEBUG:</p>
554
+ <ol>
555
+ <li>A box of the installer has no config file of its own. Copy the one of its slot first:
556
+ <code>cp /srv/tinyjukebox/current/config/tinyjukebox.yaml /srv/tinyjukebox/config/</code>.</li>
557
+ <li>In <code>/srv/tinyjukebox/config/tinyjukebox.yaml</code> set <code>log-level: DEBUG</code>.</li>
558
+ <li><code>sudo systemctl restart tinyjukebox</code>.</li>
559
+ <li>After the search, remove the copy again and restart the service: from then on the file would be the config of
560
+ every version, also of every later one.</li>
561
+ </ol>
562
+ <h3 id="74-buttons-led-and-reader"><span id="s7-4"></span>7.4 Buttons, LED and reader</h3>
563
+ <p>The tab "System" has the card "Hardware" for admins: what the drivers say about the buttons, the LED and the RFID
564
+ reader, twice a second. If a button has no effect, it shows whether the button arrives at the box at all. Checking the
565
+ hardware by hand on the console: <a href="https://tgd1975.github.io/tinyjukebox/reference/operations/#92-check-the-hardware-by-hand">operations.md</a>,
566
+ section 9.2.</p>
567
+ <hr />
568
+ <h2 id="8-configuration"><span id="s8"></span>8. Configuration</h2>
569
+ <h3 id="81-where-the-file-is"><span id="s8-1"></span>8.1 Where the file is</h3>
570
+ <table>
571
+ <thead>
572
+ <tr>
573
+ <th>Box or library</th>
574
+ <th>Config</th>
575
+ </tr>
576
+ </thead>
577
+ <tbody>
578
+ <tr>
579
+ <td>box of the installer</td>
580
+ <td>the config of its slot, <code>/srv/tinyjukebox/current/config/tinyjukebox.yaml</code>; it comes with every version</td>
581
+ </tr>
582
+ <tr>
583
+ <td>box of the playbook</td>
584
+ <td><code>/srv/tinyjukebox/config/tinyjukebox.yaml</code>, written by every run of the playbook</td>
585
+ </tr>
586
+ <tr>
587
+ <td>library on the NAS</td>
588
+ <td><code>/var/packages/tinyjukebox-library/var/library.yaml</code></td>
589
+ </tr>
590
+ <tr>
591
+ <td><code>--data DIR</code> (Docker, PC)</td>
592
+ <td>built in; <code>DIR/config.yaml</code>, if there is one, changes single values</td>
593
+ </tr>
594
+ </tbody>
595
+ </table>
596
+ <p>Most of what an admin sets is on the page and needs no file: volume limits (<a href="manual.html#10-limiting-the-volume">manual</a>,
597
+ section 10), the library of a box, update mode, backups. A change of the file takes effect after
598
+ <code>sudo systemctl restart tinyjukebox</code>.</p>
599
+ <h3 id="82-keys-an-admin-changes"><span id="s8-2"></span>8.2 Keys an admin changes</h3>
600
+ <table>
601
+ <thead>
602
+ <tr>
603
+ <th>Key</th>
604
+ <th>Meaning</th>
605
+ <th>On the box</th>
606
+ </tr>
607
+ </thead>
608
+ <tbody>
609
+ <tr>
610
+ <td><code>logger/log-level</code></td>
611
+ <td>how much the log says</td>
612
+ <td><code>INFO</code></td>
613
+ </tr>
614
+ <tr>
615
+ <td><code>tinyjukebox/rest-api/session-timeout</code></td>
616
+ <td>logout after this many seconds without a request</td>
617
+ <td><code>604800</code> (7 days)</td>
618
+ </tr>
619
+ <tr>
620
+ <td><code>tinyjukebox/rest-api/idle-timeout</code></td>
621
+ <td>logout after this many seconds in which nothing was done on an open page; <code>0</code>: never</td>
622
+ <td><code>1800</code> (30 minutes)</td>
623
+ </tr>
624
+ <tr>
625
+ <td><code>tinyjukebox/rest-api/max-upload-size</code></td>
626
+ <td>MB per uploaded MP3 file</td>
627
+ <td><code>500</code></td>
628
+ </tr>
629
+ <tr>
630
+ <td><code>tinyjukebox/sync/keep-free</code></td>
631
+ <td>MB that stay free on the card of a box with a library; when less is free, the albums not played for the longest time go</td>
632
+ <td><code>500</code></td>
633
+ </tr>
634
+ <tr>
635
+ <td><code>tinyjukebox/backups-folder</code></td>
636
+ <td>where a box without a library keeps its backups, until another folder is set on its page</td>
637
+ <td><code>backups</code> beside the albums</td>
638
+ </tr>
639
+ </tbody>
640
+ </table>
641
+ <p>Every key: <a href="https://tgd1975.github.io/tinyjukebox/reference/configuration/#4-section-tinyjukebox">configuration.md</a>, sections 4 to 6, and on the
642
+ documentation site the generated table of all keys (tab "Reference", "Configuration keys"). Unknown keys stop the
643
+ start: the message names the path of the key.</p>
644
+ <hr />
645
+ <h2 id="9-if-something-does-not-work"><span id="s9"></span>9. If something does not work</h2>
646
+ <p>The manual lists what a user can do (<a href="manual.html#12-if-something-does-not-work">manual</a>, section 12). For an admin:</p>
647
+ <table>
648
+ <thead>
649
+ <tr>
650
+ <th>Symptom</th>
651
+ <th>Look at</th>
652
+ <th>Cause and action</th>
653
+ </tr>
654
+ </thead>
655
+ <tbody>
656
+ <tr>
657
+ <td>LED stays red</td>
658
+ <td><code>sudo systemctl status tinyjukebox</code>, <code>journalctl -u tinyjukebox</code></td>
659
+ <td>the service does not run or fails on start, e.g. an invalid config: the message names the path</td>
660
+ </tr>
661
+ <tr>
662
+ <td>No tag is recognized</td>
663
+ <td>the log: <code>RFID - …</code></td>
664
+ <td>the line says why: the reader cannot be started, it does not answer (wiring, supply), or the program of the version is not trusted – then run the installer again</td>
665
+ </tr>
666
+ <tr>
667
+ <td>Web page not reachable</td>
668
+ <td><code>sudo systemctl status tinyjukebox</code></td>
669
+ <td>the service does not run; or the name <code>….local</code> is not found: use the address of the box</td>
670
+ </tr>
671
+ <tr>
672
+ <td>LED red, white, magenta, yellow in turn; nothing plays</td>
673
+ <td>tab "System"; <code>tinyjukebox-slot status</code></td>
674
+ <td>the library is too old for the version of the box: update the library (section 4.3), or go back on the box (section 4.2)</td>
675
+ </tr>
676
+ <tr>
677
+ <td>The box does not get a new version</td>
678
+ <td><code>tinyjukebox-slot status</code>, <code>tinyjukebox-slot check</code>; tab "Versions" of the library</td>
679
+ <td>update mode "by hand only" or "off"; the version is not <code>use</code>; the box went back from it before; the library has no access to the releases (section 3.7)</td>
680
+ </tr>
681
+ <tr>
682
+ <td>The box runs an older version again</td>
683
+ <td><code>/srv/tinyjukebox/state/history.log</code>, tab "Boxes" of the library</td>
684
+ <td>the new version failed its probation and the box went back; the line says why</td>
685
+ </tr>
686
+ <tr>
687
+ <td>The page of the box says the library is not connected</td>
688
+ <td>tab "System", section "Library"; the log</td>
689
+ <td>the NAS is off or not in this WLAN: the box plays what it has and delivers its changes later</td>
690
+ </tr>
691
+ <tr>
692
+ <td>The library does not start</td>
693
+ <td><code>var/server.log</code> on the NAS; <code>docker logs library</code></td>
694
+ <td>the line says why, e.g. <code>var/library.yaml</code> is missing</td>
695
+ </tr>
696
+ </tbody>
697
+ </table>
698
+ <p>More symptoms, with the lines of the log: <a href="https://tgd1975.github.io/tinyjukebox/reference/operations/#93-symptoms">operations.md</a>, section 9.3.</p>
699
+ </main>
700
+ </body>
701
+ </html>