diff --git a/documentation/content/developers/rfid/template_reader.md b/documentation/content/developers/rfid/template_reader.md index 8a1ed95fe..adcd1cdde 100644 --- a/documentation/content/developers/rfid/template_reader.md +++ b/documentation/content/developers/rfid/template_reader.md @@ -26,9 +26,7 @@ components/rfid/hardware/awesome_reader/ +- README.rst <-- The Readme ``` -The module documentation must go into a separate file so we can import -it into the Sphinx document generation flow without loading the Python -module. +Please make sure you update the documentation accordingly. ## Conventions diff --git a/documentation/sphinx/_templates/footer.html b/documentation/sphinx/_templates/footer.html deleted file mode 100644 index 0e21c0de1..000000000 --- a/documentation/sphinx/_templates/footer.html +++ /dev/null @@ -1,17 +0,0 @@ -{# If this is a local build extend the footer with this information and git state #} - -{% extends '!footer.html' %} -{% block extrafooter %} -{% if not READTHEDOCS %} -
-

- -

-

- Local copy of documentation for {{ project }} Version {{ release }}. - View online documentation - -

-
-{% endif %} -{% endblock %} diff --git a/documentation/sphinx/api/api.rst b/documentation/sphinx/api/api.rst deleted file mode 100644 index 117fe92f6..000000000 --- a/documentation/sphinx/api/api.rst +++ /dev/null @@ -1,20 +0,0 @@ ----------------------- -Developers API ----------------------- - -Developers API Introduction - -.. toctree:: - :maxdepth: 2 - :caption: The Python packages: - - plugs - publishing - rpc_server - cfghandler - playlist - utils - volume - controls - callingback - gpioz/gpioz diff --git a/documentation/sphinx/api/callingback.rst b/documentation/sphinx/api/callingback.rst deleted file mode 100644 index f913b41fd..000000000 --- a/documentation/sphinx/api/callingback.rst +++ /dev/null @@ -1,9 +0,0 @@ -.. RPI Jukebox RFID Version 3 -.. Copyright (c) See file LICENSE in project root folder - -------------------------------- -Generic Callback Handler -------------------------------- - -.. automodule:: jukebox.callingback - :members: diff --git a/documentation/sphinx/api/cfghandler.rst b/documentation/sphinx/api/cfghandler.rst deleted file mode 100644 index cfdcd078d..000000000 --- a/documentation/sphinx/api/cfghandler.rst +++ /dev/null @@ -1,5 +0,0 @@ -Config Handler -***************** - -.. automodule:: jukebox.cfghandler - :members: diff --git a/documentation/sphinx/api/controls.rst b/documentation/sphinx/api/controls.rst deleted file mode 100644 index 1ad0a2956..000000000 --- a/documentation/sphinx/api/controls.rst +++ /dev/null @@ -1,19 +0,0 @@ - -Controls based on EvDev input devices -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - -Common -************************* - -.. automodule:: components.controls.common.evdev_listener - :members: - :private-members: _filter_by_device_name, _filter_by_mandatory_keys - -Bluetooth audio buttons -************************* - -See also the corresponding user guide :ref:`userguide/bluetooth_audio_buttons:Bluetooth audio buttons` - -.. automodule:: components.controls.bluetooth_audio_buttons - :members: diff --git a/documentation/sphinx/api/gpioz/connector.rst b/documentation/sphinx/api/gpioz/connector.rst deleted file mode 100644 index eb547de55..000000000 --- a/documentation/sphinx/api/gpioz/connector.rst +++ /dev/null @@ -1,45 +0,0 @@ -.. RPI Jukebox RFID Version 3 -.. Copyright (c) See file LICENSE in project root folder - -------------------------------- -GPIOZ Connector Functions -------------------------------- - -.. automodule:: components.gpio.gpioz.plugin.connectivity - -.. currentmodule:: components.gpio.gpioz.plugin.connectivity - -Common -^^^^^^^^ - -.. autoattribute:: components.gpio.gpioz.plugin.connectivity.BUZZ_TONE - -RFID -^^^^^ - -.. autofunction:: register_rfid_callback - - -Volume -^^^^^^^^ - -.. autofunction:: register_volume_led_callback - -.. autofunction:: register_volume_rgbled_callback - -.. autofunction:: register_volume_buzzer_callback - -Audio output sink -^^^^^^^^^^^^^^^^^^ - -.. autofunction:: register_audio_sink_change_callback - -Status -^^^^^^^^ -.. autofunction:: register_status_led_callback - -.. autofunction:: register_status_buzzer_callback - -.. autofunction:: register_status_tonalbuzzer_callback - - diff --git a/documentation/sphinx/api/gpioz/converter.rst b/documentation/sphinx/api/gpioz/converter.rst deleted file mode 100644 index d65e4b595..000000000 --- a/documentation/sphinx/api/gpioz/converter.rst +++ /dev/null @@ -1,13 +0,0 @@ -.. RPI Jukebox RFID Version 3 -.. Copyright (c) See file LICENSE in project root folder - -------------------------------- -GPIOZ Converters -------------------------------- - -.. automodule:: components.gpio.gpioz.core.converter - :members: - :special-members: +__call__ - - - diff --git a/documentation/sphinx/api/gpioz/gpioz.rst b/documentation/sphinx/api/gpioz/gpioz.rst deleted file mode 100644 index 024fd90ee..000000000 --- a/documentation/sphinx/api/gpioz/gpioz.rst +++ /dev/null @@ -1,17 +0,0 @@ -.. RPI Jukebox RFID Version 3 -.. Copyright (c) See file LICENSE in project root folder - ----------------------- -GPIOZ ----------------------- - -The GPIOZ plugin connects to GPIO devices such as Buttons, LEDs, Buzzers. It utilizes GPIOZero to do so. - -.. toctree:: - :maxdepth: 2 - :caption: The GPIOZ packages: - - input_devices - output_devices - connector - converter diff --git a/documentation/sphinx/api/gpioz/input_devices.rst b/documentation/sphinx/api/gpioz/input_devices.rst deleted file mode 100644 index ba29d70f5..000000000 --- a/documentation/sphinx/api/gpioz/input_devices.rst +++ /dev/null @@ -1,42 +0,0 @@ -.. RPI Jukebox RFID Version 3 -.. Copyright (c) See file LICENSE in project root folder - -------------------------------- -GPIOZ Input Devices -------------------------------- - -.. automodule:: components.gpio.gpioz.core.input_devices - -.. currentmodule:: components.gpio.gpioz.core.input_devices - -Button -^^^^^^^^ - -.. autoclass:: Button - :members: on_press, set_rpc_actions, close, value, pull_up, pin, hold_time, hold_repeat - -Long press Button -^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -.. autoclass:: LongPressButton - :members: on_press, set_rpc_actions, close, value, pull_up, pin, hold_time, hold_repeat - -Short + Long press Button -^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -.. autoclass:: ShortLongPressButton - :members: on_short_press, on_long_press, set_rpc_actions, close, value, pull_up, pin, hold_time, hold_repeat - -Twin Button -^^^^^^^^^^^^^^^^^^^ - -.. autoclass:: TwinButton - :members: on_short_press_a, on_short_press_b, on_short_press_ab, on_long_press_a, on_long_press_b, on_long_press_ab, value, is_active, hold_repeat, hold_time, close - -Rotary Encoder -^^^^^^^^^^^^^^^^^^ - -.. autoclass:: RotaryEncoder - :members: on_rotate_clockwise, on_rotate_counter_clockwise, set_rpc_actions, close, pin_a, pin_b - - diff --git a/documentation/sphinx/api/gpioz/output_devices.rst b/documentation/sphinx/api/gpioz/output_devices.rst deleted file mode 100644 index a30986f03..000000000 --- a/documentation/sphinx/api/gpioz/output_devices.rst +++ /dev/null @@ -1,44 +0,0 @@ -.. RPI Jukebox RFID Version 3 -.. Copyright (c) See file LICENSE in project root folder - -------------------------------- -GPIOZ Output Devices -------------------------------- - -.. automodule:: components.gpio.gpioz.core.output_devices - -.. py:currentmodule:: components.gpio.gpioz.core.output_devices - - -LED -^^^ - -.. autoclass:: LED(pin, *, active_high=True, initial_value=False, pin_factory=None, name=None) - :members: flash, on, off, toggle, blink, pin, is_lit, value - -PWMLED -^^^^^^^ - -.. autoclass:: PWMLED(pin, *, active_high=True, initial_value=0, frequency=100, pin_factory=None, name=None) - :members: flash, on, off, toggle, blink, pulse, pin, is_lit, value - - -RGBLED -^^^^^^^ - -.. autoclass:: RGBLED(red, green, blue, *, active_high=True, initial_value=(0, 0, 0), pwm=True, pin_factory=None, name=None) - :members: flash, on, off, toggle, blink, pulse, red, green, blue, is_lit, color, value - - -Buzzer -^^^^^^^ - -.. autoclass:: Buzzer(pin, *, active_high=True, initial_value=False, pin_factory=None, name=None) - :members: flash, on, off, toggle, beep, pin, is_active, value - - -TonalBuzzer -^^^^^^^^^^^^^^ - -.. autoclass:: TonalBuzzer(pin, *, initial_value=None, mid_tone=Tone('A5'), octaves=2, pin_factory=None, name=None) - :members: melody, flash, play, stop, octaves, min_tone, mid_tone, max_tone, tone, is_active, value diff --git a/documentation/sphinx/api/playlist.rst b/documentation/sphinx/api/playlist.rst deleted file mode 100644 index febeb4c0f..000000000 --- a/documentation/sphinx/api/playlist.rst +++ /dev/null @@ -1,11 +0,0 @@ -Playlist Generator -********************** - -.. automodule:: jukebox.playlistgenerator - -.. autoclass:: jukebox.playlistgenerator.PlaylistCollector - :members: - :private-members: _exclude_endings - - - diff --git a/documentation/sphinx/api/plugs.rst b/documentation/sphinx/api/plugs.rst deleted file mode 100644 index 73f2e1043..000000000 --- a/documentation/sphinx/api/plugs.rst +++ /dev/null @@ -1,6 +0,0 @@ ----------------------------- -Plugs: The Plugin Package ----------------------------- - -.. automodule:: jukebox.plugs - :members: diff --git a/documentation/sphinx/api/publishing.rst b/documentation/sphinx/api/publishing.rst deleted file mode 100644 index 607d9e8d3..000000000 --- a/documentation/sphinx/api/publishing.rst +++ /dev/null @@ -1,12 +0,0 @@ -.. automodule:: jukebox.publishing.server - - jukebox.publishing - ------------------- - - .. autofunction:: jukebox.publishing.get_publisher - - jukebox.publishing.server - ------------------------- - - .. autoclass:: jukebox.publishing.server.Publisher - :members: diff --git a/documentation/sphinx/api/rpc_server.rst b/documentation/sphinx/api/rpc_server.rst deleted file mode 100644 index 634adf763..000000000 --- a/documentation/sphinx/api/rpc_server.rst +++ /dev/null @@ -1,7 +0,0 @@ -.. automodule:: jukebox.rpc.server - - jukebox.rpc.server - ------------------------- - - .. autoclass:: jukebox.rpc.server.RpcServer - :members: diff --git a/documentation/sphinx/api/utils.rst b/documentation/sphinx/api/utils.rst deleted file mode 100644 index 17ba7500c..000000000 --- a/documentation/sphinx/api/utils.rst +++ /dev/null @@ -1,6 +0,0 @@ ----------------------------- -Jukebox utility functions ----------------------------- - -.. automodule:: jukebox.utils - :members: diff --git a/documentation/sphinx/api/volume.rst b/documentation/sphinx/api/volume.rst deleted file mode 100644 index 4bf700832..000000000 --- a/documentation/sphinx/api/volume.rst +++ /dev/null @@ -1,17 +0,0 @@ -.. RPI Jukebox RFID -.. RPI Jukebox RFID -.. Copyright (c) See file LICENSE in project root folder - -------------------------------- -Volume and Audio Sink Control -------------------------------- - -.. automodule:: components.volume - -.. autoclass:: components.volume.PulseMonitor - :members: - :inherited-members: Thread - -.. autoclass:: components.volume.PulseVolumeControl - :members: - :inherited-members: Thread diff --git a/documentation/sphinx/conf.py b/documentation/sphinx/conf.py deleted file mode 100644 index 79b9476bd..000000000 --- a/documentation/sphinx/conf.py +++ /dev/null @@ -1,67 +0,0 @@ -# Configuration file for the Sphinx documentation builder. -# -# This file only contains a selection of the most common options. For a full -# list see the documentation: -# https://www.sphinx-doc.org/en/master/usage/configuration.html - -# -- Path setup -------------------------------------------------------------- - -# If extensions (or modules to document with autodoc) are in another directory, -# add these directories to sys.path here. If the directory is relative to the -# documentation root, use os.path.abspath to make it absolute, like shown here. -# -import os -import sys -import sphinx_rtd_theme -sys.path.insert(0, os.path.abspath('../../src/jukebox')) -# This is needed for autodoc to load components.plugins with regular import - i.e. w/o going through plugs.load(...) -import jukebox.plugs # noqa: E402 -jukebox.plugs.ALLOW_DIRECT_IMPORTS = True -import jukebox.utils # noqa: E402 - - -# -- Project information ----------------------------------------------------- - -project = 'RPi Jukebox RFID' -copyright = '2021-2022, The RPi Jukebox RFID Community' -author = 'The RPi Jukebox RFID Community' - -# The full version, including alpha/beta/rc tags -release = jukebox.version() -version = release - -# -- General configuration --------------------------------------------------- - -# Add any Sphinx extension module names here, as strings. They can be -# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom -# ones. -extensions = ['sphinx.ext.autodoc', 'sphinx.ext.autosectionlabel'] - -# Add any paths that contain templates here, relative to this directory. -templates_path = ['_templates'] - -# List of patterns, relative to source directory, that match files and -# directories to ignore when looking for source files. -# This pattern also affects html_static_path and html_extra_path. -exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] - - -# -- Options for HTML output ------------------------------------------------- - -# The theme to use for HTML and HTML Help pages. See the documentation for -# a list of builtin themes. -# html_theme = 'alabaster' -html_theme = 'sphinx_rtd_theme' -html_theme_path = [sphinx_rtd_theme.get_html_theme_path()] - -# Add any paths that contain custom static files (such as style sheets) here, -# relative to this directory. They are copied after the builtin static files, -# so a file named "default.css" will overwrite the builtin "default.css". -# There are none yet: Comment out to suppress warning -# html_static_path = ['_static'] - -# --------------------------------------------------- - -# Prefix document path to section labels, to use: -# `path/to/file:heading` instead of just `heading` -autosectionlabel_prefix_document = True diff --git a/documentation/sphinx/developer/coreapps.rst b/documentation/sphinx/developer/coreapps.rst deleted file mode 100644 index 887b8d143..000000000 --- a/documentation/sphinx/developer/coreapps.rst +++ /dev/null @@ -1,61 +0,0 @@ -Jukebox Apps -=============== - -The Jukebox's core apps are located in ``src/jukebox``. Run the following command to learn more about each app and its parameters: - -.. code-block:: bash - - $ ./run_app_name.py -h - -Jukebox Core -***************** - -run_jukebox.py ---------------- - -.. automodule:: run_jukebox - -Configuration Tools -******************** - -Before running the configuration tools, stop the Jukebox Core service. -See :ref:`userguide/configuration:Best practice procedure`. - -run_configure_audio.py ------------------------------ - -.. automodule:: run_configure_audio - -run_register_rfid_reader.py ------------------------------ - -.. automodule:: run_register_rfid_reader - -Developer Tools -***************** - -run_rpc_tool.py ---------------- - -.. automodule:: run_rpc_tool - -run_publicity_sniffer.py -------------------------- - -.. automodule:: run_publicity_sniffer - -run_sphinx.sh -------------------------- - -This command rebuilds the documentation using a Sphinx flow, located in the main directory. - -The documentation is built partially from auto-generated RST-files. -Thee files contain the :ref:`userguide/rpc_command_reference:RPC Command Reference` -and :ref:`userguide/rpc_command_alias_reference:RPC Command Alias Reference`. - -.. code-block:: bash - - run_jukebox.py -a - -The above command regenerate these RST files. This only needs to be done when -the RPC call references need to be updated within the documentation flow. diff --git a/documentation/sphinx/developer/developer_issues.rst b/documentation/sphinx/developer/developer_issues.rst deleted file mode 100644 index dd3a511fd..000000000 --- a/documentation/sphinx/developer/developer_issues.rst +++ /dev/null @@ -1,80 +0,0 @@ -Developer Issues -****************** - -.. contents:: - -Building the Webapp on the PI -================================== - -JavaScript heap out of memory --------------------------------- - -While (re-) building the Web App, you get the following output: - -.. code-block:: bash - :emphasize-lines: 12 - - pi@MusicPi:~/RPi-Jukebox-RFID/src/webapp $ npm run build - - > webapp@0.1.0 build - > react-scripts build - - Creating an optimized production build... - - [...] - - <--- JS stacktrace ---> - - FATAL ERROR: Reached heap limit Allocation failed - JavaScript heap out of memory - - -**Reason** - -Not enough memory for Node - -**Solution** - -Prior to building set the node memory environment variable. - - #. Make sure the value is less than the total available space on the system, or you may run into the next issue. (Not always though!) - Check memory availability with ``free -mt``. - #. We also experience trouble, when the space is set too small a value. 512 always works, 256 sometimes does, sometimes does not. - If your free memory is small, consider increasing the swap size of your system! - -.. code-block:: bash - - export NODE_OPTIONS=--max-old-space-size=512 - npm run build - -Alternatively, use the provided script, which sets the variable for you (provided your swap size is large enough): - -.. code-block:: bash - - $ ./run_rebuild.sh - - -Process exited too early // kill -9 ---------------------------------------- - -.. code-block:: bash - :emphasize-lines: 8,9 - - pi@MusicPi:~/RPi-Jukebox-RFID/src/webapp $ npm run build - - > webapp@0.1.0 build - > react-scripts build - - ... - - The build failed because the process exited too early. - This probably means the system ran out of memory or someone called 'kill -9' on the process. - -**Reason** - -Node tried to allocate more memory than available on the system. - -**Solution** - -Adjust the node memory variable as described in :ref:`developer/developer_issues:JavaScript heap out of memory`. -But make sure to allocate less memory than the available memory. -If that is not sufficient, increase the swap file size of your system and try again. diff --git a/documentation/sphinx/developer/development_environment.rst b/documentation/sphinx/developer/development_environment.rst deleted file mode 100644 index 243584eb7..000000000 --- a/documentation/sphinx/developer/development_environment.rst +++ /dev/null @@ -1,73 +0,0 @@ -Development Environment -************************ - -You have 3 development options: - -.. contents:: - -Directly on Raspberry Pi ------------------------- - -The full setup is running on the RPi and you access files via SSH. Pretty easy to set up as -you simply do a normal install and switch to the ``future3/develop`` branch. - -Steps to install -```````````````` - -We recommend to use at least a Pi 3 or Pi Zero 2 for development. This hardware won't be needed -in production, but it can be slow while developing. - -1. Install the latest Pi OS on a SD card. -2. Boot up your Raspberry Pi. -3. :ref:`Install ` the Jukebox software as if you were building a Phoniebox. You can install from your own fork and feature branch if you wish which can be changed later as well. The original repository will be set as ``upstream``. -4. Once the installation has successfully ran, reboot your Pi. -5. Due to some resource constraints, the Webapp does not build the latest changes and instead consumes the latest official release. To change that, you need to install NodeJS and build the Webapp locally. -6. Install NodeJS using the existing installer - -.. code-block:: bash - - cd ~/RPi-Jukebox-RFID/installation/routines; \ - source setup_jukebox_webapp.sh; \ - _jukebox_webapp_install_node - -7. To free up RAM, reboot your Pi. -8. Build the Webapp using the existing build command. If the build fails, you might have forgotten to reboot. - -.. code-block:: bash - - cd ~/RPi-Jukebox-RFID/src/webapp; \ - ./run_rebuild.sh -u - -9. The Webapp should now be updated. -10. To continuously update Webapp, pull the latest changes from your repository and rerun the command above. - - -Locally on any Linux machine ------------------------------- - -The jukebox also runs on any Linux machine. The Raspberry Pi specific stuff will not work of course. That is no issue depending -our your development area. USB RFID Readers, however, will work. -You may setup a Python virtual environment or a conda virtual environment. -You will have to install and configure `MPD (Music Player Daemon) `_. - -In addition to the `requirements.txt`, you will this dependency. On the Raspberry PI, the latest stable -release of ZMQ does not support WebSockets. We need to compile the latest -version from Github, which is taken care of by the installation script. -For regular machines, the normal package can be installed: - -.. code-block:: bash - - pip3 install pyzmq - - -You will have to start Jukebox core application and the WebUI separately. The MPD usually runs as a service. - -Using Docker container ------------------------------- - -There is a complete setup :ref:`docker workflow `. - -.. toctree:: - :hidden: - - docker diff --git a/documentation/sphinx/developer/docker.rst b/documentation/sphinx/developer/docker.rst deleted file mode 100644 index f3de61902..000000000 --- a/documentation/sphinx/developer/docker.rst +++ /dev/null @@ -1,250 +0,0 @@ -Phoniebox Development Runbook for Docker environments -******************************************************** - -.. contents:: - -This document describes how to set up a local development environment with Docker. -It is useful to develop certain parts of the Phoniebox application that do not directly require the Raspberry Pi -hardware such as GPIO. *Raspberry Pi OS* is based on Debian but comes with a lot of special packages and a unique -graphical interface. It is difficult to mock a Raspberry Pi whithin a Docker container but we try to keep both -environments as close as possible. The Docker environment is not meant to be deployed on the Raspberry Pi directly for -performance reasons. - -Depending on your host environment (Mac, Linux or Windows), you might need to adapt some of those commands to your needs. - -Prerequisites --------------------------- - -1. Install required software - - * Linux - - * `Docker `_ - * `Compose `_ - - * Mac: - - * `Docker & Compose (Mac) `_ - * `pulseaudio (Doc) `_ - - * Windows: - - * `Docker & Compose (Win) `_ - * `pulseaudio (Win) `_ - -2. Pull the Jukebox repository: ``git clone https://github.com/MiczFlor/RPi-Jukebox-RFID.git`` - - -3. Create a jukebox.yaml file - - * Copy the ``./resources/default-settings/jukebox.default.yaml`` to ``./shared/settings`` and - rename the file to ``jukebox.yaml``. - - ``$ cp ./resources/default-settings/jukebox.default.yaml ./shared/settings/jukebox.yaml`` - - - * Override/Merge the values from the following - `Override file - `_ - in your ``jukebox.yaml``. - -4. Change directory into the ``./RPi-Jukebox-RFID/shared/audiofolders`` and copy a set of MP3 files into this folder (for more fun when testing). - -Run development environment ------------------------------- - -In contrary to how everything is set up on the Raspberry Pi, it's good practice to isolate different components in -different Docker images. They can be run individually or in combination. -To do that, we use ``docker compose``. - -Linux -^^^^^^^ - -Make sure you don't use ``sudo`` to run your ``docker compose``. Check out Docker's `post-installation guide ` -for more information. - -.. code-block:: bash - - // Build Images - $ docker compose -f docker/docker-compose.yml -f docker/docker-compose.linux.yml build - - // Run Docker Environment - $ docker compose -f docker/docker-compose.yml -f docker/docker-compose.linux.yml up - - // Shuts down Docker containers and Docker network - $ docker compose -f docker/docker-compose.yml -f docker/docker-compose.linux.yml down - - -The docker linux setup tries to mirror the current users pulseaudio socket from ``$XDG_RUNTIME_DIR/pulse/native`` to the containers ``mpd`` and ``jukebox``. -If your pulseaudio socket is in another place, adjust path in docker/docker-compose.linux.yml. You can find out the socket path with the command ``pactl info``. -To access the socket, the user inside the docker containers also must have the same UID as the user running docker. You can find out your UID by running ``id -u``. If your UID deviates from the default UID 1000, please run ``export UID=$(id -u)`` prior to any docker commands. - -Mac -^^^^^ - -Remember, pulseaudio is a prerequisite. `Follow these instructions `_ -for Mac hosts. - -.. code-block:: bash - - // Build Images - $ docker compose -f docker/docker-compose.yml -f docker/docker-compose.mac.yml build - - // Run Docker Environment - $ docker compose -f docker/docker-compose.yml -f docker/docker-compose.mac.yml up - - // Shuts down Docker containers and Docker network - $ docker compose -f docker/docker-compose.yml -f docker/docker-compose.mac.yml down - -Windows -^^^^^^^^^^^ - -#. Download `pulseaudio `_ -#. Uncompress somewhere in your user folder -#. Edit ``$INSTALL_DIR/etc/pulse/default.pa`` -#. Add the following line - - .. code-block:: bash - - load-module module-native-protocol-tcp auth-ip-acl=127.0.0.1 - -1. Edit ``$INSTALL_DIR/etc/pulse//etc/pulse/daemon.conf``, find the following line and change it to: - - .. code-block:: bash - - exit-idle-time = -1 - -1. Execute ``$INSTALL_DIR/bin/pulseaudio.exe`` -1. Run ``cocker-compose`` - -.. code-block:: bash - - // Build Images - $ docker compose -f docker/docker-compose.yml build - - // Run Docker Environment - $ docker compose -f docker/docker-compose.yml up - - // Shuts down Docker containers and Docker network - $ docker compose -f docker/docker-compose.yml down - -Test & Develop ---------------------- - -The Dockerfile is defined to start all Phoniebox related services. - -Windows: Open `host.docker.internal:3000 `_ in your browser to see the web application. -Linux / Mac: Open `http://localhost:3000 `_ in your browser to see the web application. - - -While the ``webapp`` container does not require a reload while working on it (hot-reload is enabled), -you will have to restart your ``jukebox`` container whenever you make a change (in the Python code). -Instead of stopping and starting the ``docker compose`` command, you can individually restart your -``jukebox`` container. Update the below path with your specific host environment. - -.. code-block:: bash - - $ docker compose -f docker/docker-compose.yml -f docker/docker-compose.[ENVIRONMENT].yml restart jukebox - -Known issues ----------------- - -The docker environment only exists to make development easier and possible without a physical device. It won't -replace it though. Therefore, we currently accept certain issues related to the individual Docker containers. -Here is a list of known errors or weird behaviour which you can easily ignore unless they prevent you from progressing. -If would be of course useful to get rid of them, but currently we make a trade-off between a development environment and -solving the specific details. - -``mpd`` container -^^^^^^^^^^^^^^^^^^ - -When starting the ``mpd`` container, you will see the following errors. You can ignore them, MPD will run. - -.. code-block:: bash - - mpd | exception: bind to '0.0.0.0:6600' failed (continuing anyway, because binding to '[::]:6600' succeeded): Failed to bind socket: Address already in use - mpd | exception: Failed to open '/root/.config/mpd/database': No such file or directory - mpd | exception: RTIOThread could not get realtime scheduling, continuing anyway: sched_setscheduler failed: Operation not permitted - mpd | avahi: Failed to create client: Daemon not running - - -You might also notice the following errors after the ``mpd`` Docker ran for a while. Specifically the first error -could fill up your console, sometimes it stops with the second error message. It's not a problem, sound continues to -work. As a side effect, your CPU usage increases. Just kill the process and restart. - -.. code-block:: bash - - mpd | alsa_mixer: snd_mixer_handle_events() failed: Input/output error - mpd | exception: Failed to read mixer for 'My ALSA Device': snd_mixer_handle_events() failed: Input/output error - - -``jukebox`` container -^^^^^^^^^^^^^^^^^^^^^^ - -Many features of the Phoniebox are based on the Raspberry Pi hardware. This hardware can't be mocked in a virtual Docker -environment. As a result, a few plugins like RFID, GPIO or CPU temperature will throw errors because they can't start -successfully. Unless you want to develop such plugins, you will be able to ignore these errors. The plugin system is built in a way -that the Jukebox daemon will come up. If you want to develop plugins that require hardware support, you will have to -work on the hardware directly. - -Typical errors and following exceptions to be ignored in the Docker ``jukebox`` container are: - -.. code-block:: bash - - jukebox | 277:utils.py - jb.utils - MainThread - ERROR - CalledProcessError: Command 'git log --pretty='%h [%cs] %s %d' -n 1 --no-color' returned non-zero exit status 128. - jukebox | 287:utils.py - jb.utils - MainThread - ERROR - CalledProcessError: Command 'git describe --tag --dirty='-dirty'' returned non-zero exit status 128. - jukebox | 634:plugs.py - jb.plugin - MainThread - ERROR - Ignoring failed package load finalizer: 'rfid.finalize()' - jukebox | 635:plugs.py - jb.plugin - MainThread - ERROR - Reason: FileNotFoundError: [Errno 2] No such file or directory: '/home/pi/RPi-Jukebox-RFID/shared/settings/rfid.yaml' - ... - jukebox | 171:__init__.py - jb.host.lnx - MainThread - ERROR - Error reading temperature. Canceling temperature publisher. FileNotFoundError: [Errno 2] No such file or directory: '/sys/class/thermal/thermal_zone0/temp' - ... - jukebox | 319:server.py - jb.pub.server - host.timer.cputemp - ERROR - Publish command from different thread 'host.timer.cputemp' than publisher was created from 'MainThread'! - - - -Appendix -------------- - -Individual Docker Image -^^^^^^^^^^^^^^^^^^^^^^^^ - -Run an individual Docker container, e.g. ``jukebox``. Similarly you could run ``mpd`` or ``webapp``. - -The following command can be run on a Mac. - -.. code-block:: bash - - $ docker compose -f docker/docker-compose.yml -f docker/docker-compose.mac.yml build jukebox - $ docker compose -f docker/docker-compose.yml -f docker/docker-compose.mac.yml run --rm --name jukebox jukebox - -Resources -^^^^^^^^^^^ - -**Mac** - -* https://stackoverflow.com/questions/54702179/how-to-access-mac-os-x-microphone-inside-docker-container -* https://stackoverflow.com/questions/40136606/how-to-expose-audio-from-docker-container-to-a-mac -* https://github.com/jessfraz/dockerfiles/blob/master/pulseaudio/Dockerfile - -**Windows** - -* https://stackoverflow.com/questions/52890474/how-to-get-docker-audio-and-input-with-windows-or-mac-host# -* https://arnav.jain.se/2020/enable-audio--video-in-docker-container/ -* https://x410.dev/cookbook/wsl/enabling-sound-in-wsl-ubuntu-let-it-sing/ -* https://research.wmz.ninja/articles/2017/11/setting-up-wsl-with-graphics-and-audio.html - -**Audio** - -* https://github.com/mviereck/x11docker/wiki/Container-sound:-ALSA-or-Pulseaudio -* https://mpd.fandom.com/wiki/PulseAudio -* https://stmllr.net/blog/streaming-audio-with-mpd-and-icecast2-on-raspberry-pi/ - -**MPD** - -* https://stmllr.net/blog/streaming-audio-with-mpd-and-icecast2-on-raspberry-pi/ -* https://github.com/Tob1asDocker/rpi-mpd -* https://github.com/vimagick/dockerfiles/tree/master/mpd - -**ZMQ** - -* https://codeblog.dotsandbrackets.com/using-zeromq-with-docker/ diff --git a/documentation/sphinx/featurelist.rst b/documentation/sphinx/featurelist.rst deleted file mode 100644 index bc3769e43..000000000 --- a/documentation/sphinx/featurelist.rst +++ /dev/null @@ -1,313 +0,0 @@ -.. |[X]| unicode:: 0x2611 -.. |[ ]| unicode:: 0x2610 - -Feature Status -**************** - -**This is where we are in a nutshell:** Playing music from local folders via RFID trigger. -We also built a new WebUI to control the Jukebox from a browser. - -The are a few things that are specifically not integrated yet: playing streams, podcasts or Spotify. - -In the following is the currently implemented feature list in more detail. It also shows some of the shortcomings. -However the list is *not complete in terms of planned features*, -but probably **reflects more of where work is currently being put into**. - -**For new contributors:** If you want to port a feature from version 2.X or implement a new feature, contact us. Open an issue -or join us on in the chat room. You may pick topic marked as open below, but also any other topic missing in below list. -As mentioned, that list is not complete in terms of open features. Check the -`Contribution guide `_. -Topics marked *in progress* are already in the process of implementation by community members. - -.. contents:: - -Jukebox Core App -------------------- - -Base -^^^^^^^^ - -* |[X]| Clean up of surplus files -* |[X]| Host interface (shutdown, reboot) -* |[X]| Temperature getter - - * |[X]| Timer + Publisher - -* |[X]| RPi is_throttled getter - - * |[X]| Decode hex value to readable string (check version 2.x mqtt as reference?) - * |[X]| Timer + Publisher - -* |[X]| Git hash log information - - * |[X]| Log and publish this! - -* |[X]| Version number getter (Version number should be stored in a python file) - - * |[X]| Log and publish this - -* |[X]| Exit via RPC -* |[X]| Service restart via RPC - - * |[X]| Check if really running as a service - -* |[X]| Storage space getter / publisher (shutil.disk_usage) -* |[X]| Getter for error logs to show in WebUI - - * Get file location from FileHandlers (files may be stale!) - * Logger might be disabled or not connected - -* |[ ]| Enable/Disable debug logging from RPC -* |[X]| Publisher of errors (specialized logger handler) - - * This is a configurable logger handler in logger.yaml - -* |[X]| Basic Logging Config should enable Publisher stream handler -* |[ ]| Disable Console Stream Handler (or set to warning) when running as a service -* |[X]| Log & publish start time -* |[ ]| Method to change configuration through WebUI - - * The difficulty lies bringing the running Jukebox to accept the changes. There probably won't be a catch all solution - but rather a custom implementation for a select few features - -* |[X]| Strategy to post config changes via PubSub: Must be taken care of by the setter function modifying the property - - -Via RPC -^^^^^^^^ - -* |[X]| List of loaded / failed plugins -* |[X]| card action reference -* |[X]| Help command (available commands) - - * which basically is a plugin reference - -* |[X]| Simplified alias definitions for often used RPC commands (for RFID, GPIO, etc) - - * |[ ]| Port all previous commands - * |[X]| Reference file write-out: now also included in Sphinx documentation - * |[ ]| Export available alias definitions to RPC - * |[ ]| Base quick select on yaml file (*in progress*) - - * or write a yaml file as artifact which contains all the meta information about the functions as well? - * or include a ``get_signature`` function that returns the meta information for a given alias - -Config handler -^^^^^^^^^^^^^^^^^^^ - -* |[X]| While saving config to disk: local file change detection -* |[X]| cfghandler creates setndefault() at arbitrary depth - -ZMQ Publisher -^^^^^^^^^^^^^^^^^ - -* |[X]| Last Value Cache -* |[X]| Subscriber detection and initial status update -* |[X]| Port configuration option (WS and/or TCP) -* |[ ]| Callback registration option for plugin on topic send - - * How to interact with threads? - -Playback -^^^^^^^^^^^^^^^^^ - -* |[X]| Playlist generator - - * |[X]| Local folders - - * |[X]| Non-recursive folder play - * |[X]| Recursive folder play - - * |[X]| Podcast - * |[X]| Livestreams - * |[X]| NEW: Playback of m3u playlists (e.g. folder.m3u) ? - -* |[ ]| Folder configuration (*in progress*) - - * |[ ]| `Reference `_ - * |[ ]| Resume: Save and restore position (how interact with shuffle?) - * |[ ]| Single: Enable mpc single - * |[ ]| Shuffle: Enable mpc random (not shuffle) - - * Rename to random, as this is mpc random - - * |[ ]| Loop: Loop playlist - -MPD Player -^^^^^^^^^^^^^^^^^ - -* |[ ]| Thread safety for status information / configuration (*in progress*) -* |[ ]| Differential status post (*in progress*) -* |[ ]| Second swipe option setter via RPC (*in progress*) -* |[ ]| Before every music lib update, player should check user rights (not only after start-up) - -RFID -^^^^^^^^^^^^^^^^^ - -* |[X]| Test with Reader disabled -* |[X]| Start-up behaviour with un-configured Reader -* |[X]| Command card -> is now parameter ignore_same_id_delay -* |[X]| Revised RFID reader user-query setup script - - * |[ ]| Ask for place option - -* |[ ]| Enable config flag ? -* |[X]| Place not swipe / Timer thread - - * |[X]| Configurable card removal action - -* |[X]| Readers support - - * |[X]| USB (e.g. Neuftech) - * |[X]| RDM6300 - * |[X]| MFRC522 - * |[X]| RC532 - * |[X]| Multi-reader support - * |[X]| GUI Fake Reader for Development - * |[ ]| PC/SC Cards (what actually is this?) - -* |[X]| Publish RFID Card ID via PubSub - - * Needs to be thread safe - -* |[X]| Card reference IF via RPC - -* |[X]| Second Swipe Options -> must be part of player control (partially broken at the moment) - - * Freely configurable with an RPC call - * Ignore (nothing) - * Toggle Pause/Play - * Skip to next track - * Re-start playlist - -Cards -^^^^^^^^^^^^^^^^^ - -* |[ ]| Write a simplified card summary to - - * |[ ]| file - * |[X]| RPC - -* |[ ]| Card assignment function for WebUI - - * |[X]| Via RPC command alias definitions - * |[ ]| Full custom RPC call - -* |[X]| Remove card - -Timer -^^^^^^^^^^^^^^^ - -* |[X]| Shutdown timer -* |[X]| Play stop timer -* |[X]| Shutdown timer volume reduction - - * Decreases volume every x min until zero, then shuts down - * Needs to be cancelable - -* |[X]| Publish mechanism of timer status -* |[X]| Change multitimer function call interface such that endless timer etc wont pass the `iteration` kwarg -* |[ ]| Make timer settings persistent -* |[ ]| Idle timer - - * This needs clearer specification: Idle is when no music is playing and no user interaction is taking place - * i.e. needs information from RPC AND from player status. Let's do this when we see a little clearer about Spotify - - - -Volume -^^^^^^^^^^^^^^^^^ - -* |[X]| Jingle playback volume as fixed value in config -* |[X]| Default volume setting after boot-up -* |[X]| Max Volume -* |[X]| PulseAudio integration with event handler -* |[X]| Bluetooth support -* |[X]| Automatic audio sink toggle - - * |[ ]| Callbacks for audio sink change - -GPIO -^^^^^^^^^^^^^^^^^ - -* |[X]| All done! Read the docs at :ref:`userguide/gpioz:GPIO Recipes`! -* |[ ]| USB Buttons: It's a different category as it works similar to the RFID cards (in progress) - -WLAN -^^^^^^^^^^^^^^^^^ - -* |[X]| Ad-hoc WLAN Hot spot -* |[X]| IP address read-out - -Spotify -^^^^^^^^^^^^^^^^^ - -* |[ ]| Everything - -Others -^^^^^^^^^^^^^^^^^ - -* |[ ]| MQTT -* |[ ]| Record and Playback using a Mic -* |[ ]| Dot Matrix Displays - -Start-up stuff -^^^^^^^^^^^^^^^^^ - -* |[X]| check music folder permissions -* |[X]| mpc update / (mpc rescan) -* |[X]| sudo iwconfig wlan0 power off (need to be done after every restart) -* |[X]| Optional power down HDMI circuits: /usr/bin/tvservice -o - - -Debug Tools --------------- - -* |[X]| Publishing Sniffer - - * |[ ]| Update mode vs linear mode ? - -* |[X]| RPC command line client - - * |[X]| with tab-completion and history - - -WebUI --------------- - -* |[X]| Playback Control -* |[X]| Cover Art -* |[X]| Register cards / Delete cards -* |[X]| Shutdown button -* |[ ]| Settings configuration page -* |[ ]| System information page - - * |[ ]| Configure (one or multiple) WLANs - * |[X]| Enable/Disable Auto-Hotspot - -* |[X]| ``run_npm_build`` script - - * |[X]| Must consider ``export NODE_OPTIONS=--max-old-space-size=512`` - - -Installation Procedure ------------------------ - -* |[X]| Single call installation script -* |[X]| Query for settings vs. automatic version -* |[X]| IPQoS in SSH config -* |[X]| Separate static IP and IPv6 disable -* |[ ]| For all system config file changes, check prior to modification, if modification already exists - - -Documentation --------------- - -* |[X]| Sphinx / Restructured Text tool flow -* |[ ]| What is the Phoniebox -* |[X]| Artifacts: Generate artifacts (on command line switch only) for - - * |[X]| loaded plugins and rpc command aliases (to sphinx and shared/artifcats) - * |[X]| rpc command aliases (to sphinx and shared/artifcats) - -* |[ ]| How to: Write a plugin diff --git a/documentation/sphinx/index.rst b/documentation/sphinx/index.rst deleted file mode 100644 index a83777673..000000000 --- a/documentation/sphinx/index.rst +++ /dev/null @@ -1,57 +0,0 @@ -.. RPi Jukebox for Kids documentation master file, created by - sphinx-quickstart on Sun Sep 26 15:26:31 2021. - You can adapt this file completely to your liking, but it should at least - contain the root `toctree` directive. - -Welcome to RPi Jukebox RFID's documentation! -================================================ - -.. include:: primer.rst - -.. toctree:: - :maxdepth: 2 - :caption: Getting Started: - - featurelist - install - migration - issues - -.. toctree:: - :maxdepth: 2 - :caption: User Guide: - - userguide/concepts - userguide/system - userguide/configuration - userguide/audio - userguide/troubleshooting - rfid/rfid - userguide/gpioz - userguide/bluetooth_audio_buttons - userguide/rpc_commands - userguide/rpc_command_reference - userguide/rpc_command_alias_reference - userguide/carddatabase - userguide/autohotspot - userguide/sync_rfidcards - - -.. toctree:: - :maxdepth: 2 - :caption: Developer Reference: - - developer/developer_issues.rst - developer/coreapps - developer/development_environment - api/api.rst - - - - -Indices and tables -================== - -* :ref:`genindex` -* :ref:`modindex` -* :ref:`search` diff --git a/documentation/sphinx/migration.rst b/documentation/sphinx/migration.rst deleted file mode 100644 index 8d3599953..000000000 --- a/documentation/sphinx/migration.rst +++ /dev/null @@ -1,55 +0,0 @@ -Updating -************** - -Updating from Version 3.0 to 3.1 ---------------------------------------- - -There are a number of significant changes to the overall system setup, which require a fresh install. Notable changes in this respect include: - - #. Shift system setup to PulseAudio - #. Run MPD as user-local service - #. Run Jukebox Daemon as user local service - -.. important:: You need re-install on a fresh SD card! - A git pull procedure as described below will not work! - - -Updating your Jukebox Version 3 -------------------------------------- - -Things on Version 3 are moving fast and you may want to keep up with recent changes. Since we are in Alpha Release stage, -a fair number of fixes are expected to be committed in the near future. - -You will need to do three things to update your version from develop (or the next release candidate version) - -#. Pull the newest code base from Github -#. Check for new entries in the configuration -#. Re-build the WebUI - -.. code-block:: bash - - # Switch to develop (if desired) - $ git checkout future3/develop - - # Get latest code - $ git pull - - # Check if new (mandatory) options appeared in jukebox.yaml - # with your favourite diff tool and merge them - $ diff shared/settings/jukebox.yaml resources/default-settings/jukebox.default.yaml - - $ cd src/webapp - $ ./run_rebuild.sh - - -Migration Path from Version 2 -------------------------------------- - -There is no update path coming from Version 2.x of the Jukebox. -You need to do a fresh install of Version 3 on a fresh Raspian Bullseye image. - -.. important:: Do start with a fresh SD card image! - -Do not just pull the future3 branch into you existing Version 2.x directory. -Do not run the installer on an system that had Version 2.x running before on it. -Stuff has changed too much to make this feasible. diff --git a/documentation/sphinx/primer.rst b/documentation/sphinx/primer.rst deleted file mode 100644 index 90de9f916..000000000 --- a/documentation/sphinx/primer.rst +++ /dev/null @@ -1,39 +0,0 @@ -What is this? -================================================ - -The exciting, new **Version 3** of the RPi Jukebox RFID. A complete rewrite of the Jukebox code base. - -.. important:: This documentation applies to the Version 3 which is developed in the branches *future3/main* and *future3/develop*. - Currently the default Version is 2.X - -To find out more about the RPi Jukebox RFID -project check out the `documentation of Version 2 `_ or `www.phoniebox.de `_. - -Why? ------ - -* Better extensibility, clear architecture allowing for easier integration of new features -* Higher performance especially on lower end hardware (it's a stretch at the moment) -* Better maintainability -* Better observability for debugging - -How? ------- - -* Jukebox core is a holistic Python3-only application -* Avoid shell script invocation during runtime wherever possible -* Establish a socket based API (using ZeroMQ) toward the WebUI or other clients -* Implemented a Remote-Procedure-Call (RPC) server through which all user function calls pass -* Implemented a plugin concept to dynamically load Python modules configurable through the configuration file -* In conjunction with the RPC, this is a neat way of allowing additional features without having to touch the core all the time - -Where are we? Help wanted! --------------------------- - -The initial proof-of-concept phase has been left behind and there is quite some functionality available already. -This is still an ongoing process but the WebUI and RFID-triggered playback of local files work. - -Features/files from version 2.X will only be copied/merged once they can be integrated and tested. -If you don't find your v2.X contributions, it doesn't mean they are obsolete. Things will be integrated step by step. -And, of course, you are welcome to adapt your previous contributions to this new exiting structure. - diff --git a/documentation/sphinx/requirements.txt b/documentation/sphinx/requirements.txt deleted file mode 100644 index e169c2c69..000000000 --- a/documentation/sphinx/requirements.txt +++ /dev/null @@ -1,8 +0,0 @@ -# These are just the additional RTD-specific requirements -readthedocs-sphinx-search - -# Install packages for documentation build from package repository -# that are installed on the PI via APT -RPi.GPIO -gpiozero<2.0.0;python_version<'3.8' -gpiozero;python_version>='3.8' diff --git a/documentation/sphinx/requirements_pyzmq.txt b/documentation/sphinx/requirements_pyzmq.txt deleted file mode 100644 index e2a37a6e1..000000000 --- a/documentation/sphinx/requirements_pyzmq.txt +++ /dev/null @@ -1,5 +0,0 @@ -# For operation of the Jukebox, -# ZMQ must be compiled from sources due to Websocket support -# When just building the docs, the regular ZMQ package is sufficient - -pyzmq diff --git a/documentation/sphinx/rfid/basics.rst b/documentation/sphinx/rfid/basics.rst deleted file mode 100644 index 7bc49ddeb..000000000 --- a/documentation/sphinx/rfid/basics.rst +++ /dev/null @@ -1,91 +0,0 @@ -Basics ---------- - -Cards placed on the reader trigger an action. An action may be any callable plugin function through the RPC with any arguments. -Typically, this would be "play some folder", but can also be "activate shutdown timer", or "increase volume". -This is configured in the :ref:`userguide/carddatabase:Card Database`. - -You may configure a single or even multiple parallel readers (of different or identical types). - -Successive card swipes are suppressed to avoid bouncing effects. This behavior can be deactivated for individual cards. - -Reader Types ------------- - -place-capable: - Some readers give a single event signal when the card is placed on the reader. This is sufficient - to build a fully-featured Jukebox. Other readers give a continuous signal. They allow both card placements - and card removals. This can be used to play the Jukebox when a card is placed and to pause it when it's removed. - - Generally, **not** all :ref:`USB-based RFID readers ` are place-capable. - - The known place-capable readers are :ref:`RDM6300 `, - :ref:`MFRC522 ` or - :ref:`PN532 `. - -Frequency: - Readers operate on one of two different frequencies: 125kHz or 13.56 MHz. - Make sure to buy compatible cards, RFID stickers or key fobs working with the same frequency as the reader. - -Reader Configuration ------------------------ - -During the installation process, you can already configure a RFID reader. To manually configure RFID reader(s), -:ref:`please run the tool ` ``src/jukebox/run_register_rfid_reader.py``. - -It will generate a reader configuration file at ``shared/settings/rfid.yaml``. -You can re-run the tool to change the settings any time. - -Some options are not covered by the tool. You may change the file manually. - -.. code-block:: yaml - - rfid: - readers: - read_00: - module: fake_reader_gui - config: .... - same_id_delay: float|integer - log_ignored_cards: true|false - place_not_swipe: - enabled: true|false - card_removal_action: - alias: pause - -For each reader, there is an entry ``read_XX``. - -module: - Indicates the Python package used for this reader. Filled by the RFID configuration tool. - -config: - Filled by the - :ref:`RFID configuration tool ` ``src/jukebox/run_register_rfid_reader.py`` - based on default values and user input. - After running the tool, you may manually change some settings here, as not everything can - be configured through the tool. Note that re-running the tool will completely rewrite the - configuration file. - -same_id_delay: float | integer - Minimum delay in seconds between 2 card detections before triggering a new action. This - is to prevent double triggering or bouncing. - -place_not_swipe: true | false - For place-capable RFID readers enable dual action mode: - a start action (e.g. playing) on card placement and card removal action (e.g. pause). - -card_removal_action: Dictionary - Executes the given function on card removal. Only relevant if place_not_swipe is true. The action is identical for all cards read on - that reader. The removal-action can be set to ignored on a card-by-card basis. - More on card action configurations in :ref:`userguide/rpc_commands:RPC Commands`. - - Developer's note: The reason for a unique removal action for all cards is that card triggering and card removal are happening - in two separate threads. Removal needs to be in a time-out thread. Thus, we would need to transport information from - one thread to another. This can be done of course but is not implemented (yet). Ignoring card removal is much easier and works for now. - -log_ignored_cards: true | false - Log all cards that are ignored due to same_id_delay. This is a option for developers. Don't use it unless you need it for debugging as it has - the potential to spam your log files. - -Second Swipe - Looking for 'Second Swipe' option? That is part of the Player configuration and not part of the RFID configuration, as - the 'Second Swipe' action needs to take into account the player state, which can also be altered through the WebUI. diff --git a/documentation/sphinx/rfid/genericusb.rst b/documentation/sphinx/rfid/genericusb.rst deleted file mode 100644 index 03ef2c4ef..000000000 --- a/documentation/sphinx/rfid/genericusb.rst +++ /dev/null @@ -1 +0,0 @@ -.. include:: ../../../src/jukebox/components/rfid/hardware/generic_usb/README.rst \ No newline at end of file diff --git a/documentation/sphinx/rfid/mfrc522_spi.rst b/documentation/sphinx/rfid/mfrc522_spi.rst deleted file mode 100644 index ac57bda26..000000000 --- a/documentation/sphinx/rfid/mfrc522_spi.rst +++ /dev/null @@ -1 +0,0 @@ -.. include:: ../../../src/jukebox/components/rfid/hardware/rc522_spi/README.rst diff --git a/documentation/sphinx/rfid/mock_reader.png b/documentation/sphinx/rfid/mock_reader.png deleted file mode 100644 index ca9478e3b..000000000 Binary files a/documentation/sphinx/rfid/mock_reader.png and /dev/null differ diff --git a/documentation/sphinx/rfid/mock_reader.rst b/documentation/sphinx/rfid/mock_reader.rst deleted file mode 100644 index 8acb618ec..000000000 --- a/documentation/sphinx/rfid/mock_reader.rst +++ /dev/null @@ -1 +0,0 @@ -.. include:: ../../../src/jukebox/components/rfid/hardware/fake_reader_gui/README.rst diff --git a/documentation/sphinx/rfid/pn532_i2c.rst b/documentation/sphinx/rfid/pn532_i2c.rst deleted file mode 100644 index 849fc6e05..000000000 --- a/documentation/sphinx/rfid/pn532_i2c.rst +++ /dev/null @@ -1 +0,0 @@ -.. include:: ../../../src/jukebox/components/rfid/hardware/pn532_i2c_py532/README.rst \ No newline at end of file diff --git a/documentation/sphinx/rfid/rdm6300.rst b/documentation/sphinx/rfid/rdm6300.rst deleted file mode 100644 index e84643e77..000000000 --- a/documentation/sphinx/rfid/rdm6300.rst +++ /dev/null @@ -1 +0,0 @@ -.. include:: ../../../src/jukebox/components/rfid/hardware/rdm6300_serial/README.rst \ No newline at end of file diff --git a/documentation/sphinx/rfid/rfid.rst b/documentation/sphinx/rfid/rfid.rst deleted file mode 100644 index ad7c00d24..000000000 --- a/documentation/sphinx/rfid/rfid.rst +++ /dev/null @@ -1,14 +0,0 @@ ----------------------- -RFID Readers ----------------------- - -.. toctree:: - :maxdepth: 2 - - basics - genericusb - rdm6300 - mfrc522_spi - pn532_i2c - mock_reader - template diff --git a/documentation/sphinx/rfid/template.rst b/documentation/sphinx/rfid/template.rst deleted file mode 100644 index 70d01622b..000000000 --- a/documentation/sphinx/rfid/template.rst +++ /dev/null @@ -1 +0,0 @@ -.. include:: ../../../src/jukebox/components/rfid/hardware/template_new_reader/README.rst \ No newline at end of file diff --git a/documentation/sphinx/userguide/audio.rst b/documentation/sphinx/userguide/audio.rst deleted file mode 100644 index 51b7b9a40..000000000 --- a/documentation/sphinx/userguide/audio.rst +++ /dev/null @@ -1,152 +0,0 @@ -Audio Configuration -==================== - -The Jukebox supports 2 audio outputs, primary and secondary. The **primary output** is the default output and must -be available after system boot. This will typically be your sound card or the Pi's built-in headphone output. - -The **secondary output** is an optional alternative output where the audio stream can be routed to. -Stream transfer happens on user input or automatically on the connection of an audio device. -This is mainly targeted at Bluetooth Headsets/Speakers. - -Audio outputs run via PulseAudio and the basic configuration should be easy. -There is a :ref:`configuration tool`, -to setup the configuration for the Jukebox Core App. - -To set up the audio - - #. Follow the setup steps according to your sound card - #. Check that the sound output works :ref:`as described below` - #. Run the the tool :ref:`developer/coreapps:run_configure_audio.py` - #. :ref:`Fine-tune audio parameters` - -Checking system sound output -------------------------------- - -Run the following steps in a console: - -.. code-block:: bash - - # Check available PulseAudio sinks - $ pactl list sinks short - 0 alsa_output.platform-soc_sound.stereo-fallback module-alsa-card.c s16le 2ch 48000Hz - 1 bluez_sink.C4_FB_20_63_CO_FE.a2dp_sink module-bluez5-device.c s16le 2ch 44100Hz - - # Set the default sink (this will be reset at reboot) - $ pactl set-default-sink sink_name - - # Check default sink is correctly set - $ pactl info - .... - # Check volume level (exit with ESC) - $ alsamixer - - # Play a sound - $ paplay /usr/share/sounds/alsa/Front_Center.wav - - # This must also work when using an ALSA device - $ aplay /usr/share/sounds/alsa/Front_Center.wav - -You can also try different PulseAudio sinks without setting the default sink. In this case the volume is the last used -volume level for this sink: - -.. code-block:: bash - - $ paplay -d sink_name /usr/share/sounds/alsa/Front_Center.wav - - -Bluetooth ------------ - -Bluetooth setup consists of three steps - - #. Pair and connect your Bluetooth device - #. Check the output works - #. Re-run the config tool - -To pair and connect, follow these steps. This will be a one-time setup. - -.. code-block:: bash - - $ bluetoothctl - Agent registered - [CHG] Controller B8:27:EB:44:C4:33 Pairable: yes - #### Put your headset into pairing mode - [bluetooth]# scan on - Discovery started - #### Wait a few seconds for your device to appear - .... - [NEW] Device C4:FB:20:63:CO:FE PowerLocus Buddy - .... - [bluetooth]# scan off - .... - [bluetooth]# pair C4:FB:20:63:CO:FE - .... - Pairing successful - .... - [bluetooth]# trust C4:FB:20:63:CO:FE - .... - [bluetooth]# connect C4:FB:20:63:CO:FE - .... - [PowerLocus Buddy]# exit - - -Wait for a few seconds and then with ``$ pactl list sinks short``, check wether the Bluetooth device shows up as an output. -Its name usually looks like this: ``bluez_sink.C4_FB_20_63_CO_FE.a2dp_sink``. - -Run through steps in `Checking system sound output` to check wether the output is working or not. -If it does not work immediately, turn your headset off and on to force a reconnect. - -Rerun the config tool to register the Bluetooth device with the Jukebox core app as its secondary audio output. - -Additional options -------------------- - -For other audio configuration options, please look at the ``jukebox.yaml`` for now. - -Directly edit ``jukebox.yaml`` following the steps: :ref:`userguide/configuration:Best practice procedure`. - - -Developer Information ------------------------ - -The optional processing stages *Equalizer* and *Mono down mix* are realized by PulseAudio plugins. -The processing chain is - -.. code-block:: text - - player --> mono mix --> equalizer --> hardware sink - -Both plugins (if enabled) appear in the PulseAudio sinks - -.. code-block:: bash - - $ pactl list sinks short - ... - -Which means we can put any of these as sink into the jukebox configuration file (if there is any need). - -Mono down mix is enabled by the module ``module-remap-sink`` -for which `documentation and an example can be found here -`_. - -The equalizer is the PulseAudio module ``module-ladspa-sink`` with the `corresponding documentation -`_. - -This in turn loads a `LADSPA plugin `_. -The LADSPA plugin in the ``Eq10X2`` plugin of the `CAPS Library `_ -The CAPS library is available as linux package ``caps``. - -This is the same plugin which is used in the -`equalizer for pure ALSA `_ -configurations which is part of the linux package ``libasound2-plugin-equal``. - -You are, of course, free to modify the PulseAudio configuration to your needs. References - - #. `PulseAudio Documentation `_ - #. `PulseAudio Examples `_ - -In this case, run the configuration tool with below parameter to avoid touching the PulseAudio configuration file. - -.. code-block:: bash - - $ ./run_configure_audio.py --ro_pulse diff --git a/documentation/sphinx/userguide/autohotspot.rst b/documentation/sphinx/userguide/autohotspot.rst deleted file mode 100644 index 9156412b1..000000000 --- a/documentation/sphinx/userguide/autohotspot.rst +++ /dev/null @@ -1,112 +0,0 @@ -Auto-Hotspot -************ - -The Auto-Hotspot function allows the Jukebox to switch between its connection between a known WiFi and an automatically -generated hotspot so that you can still access via SSH or Webapp. - -.. important:: Please configure the WiFi connection to your home access point before enabling these feature! - -To create a hotspot and allow clients to connect `hostapd` [1]_ and `dnsmasq` [2]_ - -How to connect --------------- - -When the Jukebox is not able to connect to a known WiFi it will create a hotspot named ``Phoniebox_Hotspot``. You will be -able to connect to this hotspot using the given password in the installation or the default password: ``PlayItLoud!`` - -Webapp -^^^^^^ - -After connecting to the ``Phoniebox_Hotspot`` you are able to connect to the webapp accessing the website `10.0.0.5 `_ - -ssh -^^^ - -After connecting to the ``Phoniebox_Hotspot`` you are able to connect via ssh to your Jukebox - -.. code-block:: bash - - ssh pi@10.0.0.5 - - -Changing basic configuration of the hotspot -------------------------------------------- - -The whole hotspot configuration can be found at ``/etc/hostapd/hostapd.conf``. - -The following parameters are relevant: - -* ``ssid`` for the displayed hotspot name -* ``wpa_passphrase`` for the password of the hotspot -* ``country_code`` the country you are currently in - -.. code-block:: bash - - $ cat /etc/hostapd/hostapd.conf - - #2.4GHz setup wifi 80211 b,g,n - interface=wlan0 - driver=nl80211 - ssid=Phoniebox_Hotspot - hw_mode=g - channel=8 - wmm_enabled=0 - macaddr_acl=0 - auth_algs=1 - ignore_broadcast_ssid=0 - wpa=2 - wpa_passphrase==PlayItLoud! - wpa_key_mgmt=WPA-PSK - wpa_pairwise=CCMP TKIP - rsn_pairwise=CCMP - - #80211n - Change GB to your WiFi country code - country_code=DE - ieee80211n=1 - ieee80211d=1 - -Disabling automatism --------------------- - -Auto-Hotspot can be enabled or disabled using the Webapp. - -.. important:: Disabling or enabling will keep the last state. - -Troubleshooting --------------------- - -Phoniebox is not connecting to the known WiFi -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -The script will fall back to the hotspot so you still have some type of connection. - -Check your password in ``/etc/wpa_supplicant/wpa_supplicant.conf``. - -AutoHotspot functionality is not working -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -You can check the output of the script by running the following script: - -.. code-block:: bash - - $ sudo /usr/bin/autohotspot - -You need to add a new wifi network to the Raspberry Pi -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -Because it is in Auto-Hotspot mode, you won't be able to scan for new wifi signals. - -You will need to add a new network to ``/etc/wpa_supplicant/wpa_supplicant.conf`` manually. Enter the following details -replacing mySSID and myPassword with your details. If your WiFi has a hidden SSID then include the line ``scan_ssid=1``. - -Resources ---------- - -`Raspberry Pi - Auto WiFi Hotspot Switch - Direct Connection `__ - ------------- - -References: - -.. [1] http://w1.fi/hostapd/ -.. [2] https://thekelleys.org.uk/dnsmasq/doc.html diff --git a/documentation/sphinx/userguide/bluetooth_audio_buttons.rst b/documentation/sphinx/userguide/bluetooth_audio_buttons.rst deleted file mode 100644 index b935edb36..000000000 --- a/documentation/sphinx/userguide/bluetooth_audio_buttons.rst +++ /dev/null @@ -1,4 +0,0 @@ -Bluetooth audio buttons -************************* - -.. include:: ../../../src/jukebox/components/controls/bluetooth_audio_buttons/README.rst \ No newline at end of file diff --git a/documentation/sphinx/userguide/carddatabase.rst b/documentation/sphinx/userguide/carddatabase.rst deleted file mode 100644 index d0b40a903..000000000 --- a/documentation/sphinx/userguide/carddatabase.rst +++ /dev/null @@ -1,94 +0,0 @@ -Card Database -***************** - -In the card database, an RPC command is assigned to every card. - -This RPC command is called every time when the card is swiped (or placed) on the reader. Every -RPC callable function can be called. See :ref:`userguide/rpc_commands:RPC Commands` for an introduction. - -The card database is stored in ``shared\settings\cards.yaml``. -Here are some examples for RPC command assignments to cards '0001' to '0003' using the alias option: - -.. important:: Card IDs **must** be strings! So, be sure to quote numbers! - -.. code-block:: yaml - - '0001': - # A RPC command using the alias definition without any arguments - # Here: pause playback - alias: pause - '0002': - # A RPC command using the alias definition with one arguments - # Here: Trigger music playback through the card interface - alias: play_card - args: [path/to/folder] - '0003': - # A RPC command using keyword arguments. Args and kwargs can also be mixed. - # Args and Kwargs translate directly into the function python call - # Some as in '0002' but using kwargs - alias: play_card - kwargs: - folder: path/to/folder - -.. note:: - * Remember card ids must be strings! So, quote them! - * *args* must be a **list** of arguments to be passed! Even if ony a single argument is passed. So, use *args: [value]*. - We try catch mis-uses but that might not always work. - -Additional options -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -In addition to the RPC commands, these options may be specified for every card - -ignore_card_removal_action: true | false (default: false) - Only applies when using a place-capable reader and *place_not_swipe* is *true*. This option is ignored otherwise, - so it does not hurt. - - Do not execute card removal action, when this card is removed from the reader. Useful for command card, - that e.g. enable the shutdown timer - - .. code-block:: yaml - - '0004': - alias: timer_shutdown - ignore_card_removal_action: true - - -ignore_same_id_delay: true | false (default: false) - Override the ``same_id_delay`` parameter from the reader configuration for this card. - If true, the ``same_id_delay`` for this card is treated as 0. - This makes sense e.g., for an "increase volume" card in combination with a place-capable RFID reader. - As long as the card is placed on the reader, the volume is increased. - - .. note:: This parameter causes *ignore_card_removal_action* to be treated as true - - .. code-block:: yaml - - '0005': - alias: incr_volume - ignore_same_id_delay: true - ignore_card_removal_action: true - -Full RPC action specification -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -You have seen some examples card actions using the *alias* configuration. A full RPC action can also be specified -using the following syntax: - -.. code-block:: yaml - - '0006': - # Option 1: Omit the keyword 'alias' - # Here: Set the volume to level 12 - package: volume - plugin: ctrl - method: set_volume - args: [12] - '0007': - # Option 2: Set 'alias' to custom - # Here: Set the volume to level 12 - alias: custom - package: volume - plugin: ctrl - method: set_volume - args: [12] diff --git a/documentation/sphinx/userguide/concepts.rst b/documentation/sphinx/userguide/concepts.rst deleted file mode 100644 index 19d5d37e5..000000000 --- a/documentation/sphinx/userguide/concepts.rst +++ /dev/null @@ -1,46 +0,0 @@ -Concepts -================================================ - -The Jukebox is based on three concepts. Don't worry we won't dive into all the juicy developer details (just yet). -But a rough understanding is important as an foundation to understand the configuration files. - -Plugin Interface ----------------- - -The core app is centered around a plugin concept. This serves three purposes: - - #. Dynamically load packages with additional functionality based on configuration files. - #. Initialize and close these packages at app start / close. This happens automatically in the background. Failing - packages (for any reason) are ignored during start-up. So when some functionality is not available, always - check the logs to ensure all packages have loaded successfully! See :ref:`userguide/troubleshooting:Troubleshooting`. - #. Register and present functions which can be called via the :ref:`userguide/concepts:Remote Procedure Call Server (RPC)` - -That's about what you need to know for the plugin concept. Developer detailed information -can be found here (TBD). - -Remote Procedure Call Server (RPC) --------------------------------------- - -The Remote Procedure Call (RPC) server allows to remotely trigger actions (e.g., from the Webapp) within the Jukebox core application. -Only Python functions registered by the plugin interface can be called. This -simplifies external APIs and let's us focus on the relevant user functions. - -Why should you care? Because we use the same protocol when triggering actions from other inputs like a card swipe, a -GPIO button press, etc. How that works is described in :ref:`userguide/rpc_commands:RPC Commands`. - -You will find a full list of RPC callable functions in :ref:`userguide/rpc_command_reference:RPC Command Reference` -and aliases for convinience in :ref:`userguide/rpc_command_alias_reference:RPC Command Alias Reference` - -For developers the details can be found here (TBD). We also have a tool to send RPC commands to the running Jukebox application: -:ref:`developer/coreapps:run_rpc_tool.py` - -Publishing Message Queue --------------------------- - -The Publishing Message Queue is the complimentary part to the RPC where the core application publishes its status and status updates. -As a user, you need not worry about it. - -If you want to interact with the Jukebox from your own application, this is where you get the current -state from. Details about the protocol can be found here (TBD). A sniffer tool exists which listens and prints the incoming -status messages: :ref:`developer/coreapps:run_publicity_sniffer.py`. - diff --git a/documentation/sphinx/userguide/configuration.rst b/documentation/sphinx/userguide/configuration.rst deleted file mode 100644 index ac40b16d7..000000000 --- a/documentation/sphinx/userguide/configuration.rst +++ /dev/null @@ -1,43 +0,0 @@ -Jukebox Configuration -======================= - -The Jukebox configuration is managed by set of files located in ``../shared/settings``. -Some configuration changes can be made through the WebUI and take immediate effect. - -The majority of configuration options is only available by editing the config files - -*when the service is not running!* -Don't fear (overly), they contain commentaries. - -For several aspects we have :ref:`developer/coreapps:Configuration Tools` and detailed guides: - - * :ref:`userguide/audio:Audio Configuration` - * :ref:`RFID Reader Configuration` - -Even after running the tools certain aspects can only be changed by modifying the configuration files directly. - -Best practice procedure -------------------------- - -.. code-block:: bash - - # Make sure the Jukebox service is stopped - $ systemctl --user stop jukebox-daemon - - # Edit the file(s) - $ nano ./shared/settings/jukebox.yaml - - # Start Jukebox in console and check the log output (optional) - $ ./src/jukebox/run_jukebox.py - # and if OK, press Ctrl-C and restart the service - - # Restart the service - $ systemctl --user start jukebox-daemon - - -To try different configurations, you can start the Jukebox with a custom config file. -This could be useful if you want your Jukebox to only allow a lower volume when started -at night time when there is time to go to bed :-) - -.. code-block:: bash - - $./run_jukebox.py --conf ../path/to/custom/config.yaml diff --git a/documentation/sphinx/userguide/gpioz.rst b/documentation/sphinx/userguide/gpioz.rst deleted file mode 100644 index 5ba83d97a..000000000 --- a/documentation/sphinx/userguide/gpioz.rst +++ /dev/null @@ -1 +0,0 @@ -.. include:: ../../../src/jukebox/components/gpio/gpioz/README.rst \ No newline at end of file diff --git a/documentation/sphinx/userguide/mock_gpio.png b/documentation/sphinx/userguide/mock_gpio.png deleted file mode 100644 index f92bb21f9..000000000 Binary files a/documentation/sphinx/userguide/mock_gpio.png and /dev/null differ diff --git a/documentation/sphinx/userguide/rpc_command_alias_reference.rst b/documentation/sphinx/userguide/rpc_command_alias_reference.rst deleted file mode 100644 index e5dfc2cb5..000000000 --- a/documentation/sphinx/userguide/rpc_command_alias_reference.rst +++ /dev/null @@ -1,188 +0,0 @@ -RPC Command Alias Reference -*************************** - - -.. |--| unicode:: U+2014 -.. |->| unicode:: U+21d2 - -.. py:function:: play_card(...) -> player.ctrl.play_card(folder: str, recursive: bool = False) - :noindex: - - **Play music folder triggered by card swipe** - - Main entry point for trigger music playing from RFID reader. Decodes second swipe options before playing folder content - - Checks for second (or multiple) trigger of the same folder and calls first swipe / second swipe action - accordingly. - - :param folder: Folder path relative to music library path - :param recursive: Add folder recursively - - .. note:: This function you'll want to use most often - -.. py:function:: play_album(...) -> player.ctrl.play_album(albumartist: str, album: str) - :noindex: - - **Play Album triggered by card swipe** - - Playback a album found in MPD database. - - All album songs are added to the playlist - The playlist is cleared first. - - :param albumartist: Artist of the Album provided by MPD database - :param album: Album name provided by MPD database - - .. note:: This function plays the content of a given album - -.. py:function:: play_single(...) -> player.ctrl.play_single(song_url) - :noindex: - - **Play a single song triggered by card swipe** - - - - .. note:: This function plays the content of a given song URL - -.. py:function:: play_folder(...) -> player.ctrl.play_folder(folder: str, recursive: bool = False) -> None - :noindex: - - **Play a folder URL triggered by card swipe** - - Playback a music folder. - - Folder content is added to the playlist as described by :mod:`jukebox.playlistgenerator`. - The playlist is cleared first. - - :param folder: Folder path relative to music library path - :param recursive: Add folder recursively - - .. note:: This function plays the content of a given folder URL - -.. py:function:: pause(...) -> player.ctrl.pause(state: int = 1) - :noindex: - - Enforce pause to state (1: pause, 0: resume) - - This is what you want as card removal action: pause the playback, so it can be resumed when card is placed - on the reader again. What happens on re-placement depends on configured second swipe option - - .. note:: This is what you want as card removal action for place capable readers - - Default actions modifiers - **ignore_card_removal_action** |--| True - -.. py:function:: next_song(...) -> player.ctrl.next() - :noindex: - - Play next track in current playlist - - Default actions modifiers - **ignore_card_removal_action** |--| True - -.. py:function:: prev_song(...) -> player.ctrl.prev() - :noindex: - - - - Default actions modifiers - **ignore_card_removal_action** |--| True - -.. py:function:: toggle(...) -> player.ctrl.toggle() - :noindex: - - Toggle pause state, i.e. do a pause / resume depending on current state - - Default actions modifiers - **ignore_card_removal_action** |--| True - -.. py:function:: set_volume(...) -> volume.ctrl.set_volume(volume: int) - :noindex: - - Set the volume (0-100) for the currently active output - - Default actions modifiers - **ignore_card_removal_action** |--| True - -.. py:function:: change_volume(...) -> volume.ctrl.change_volume(step: int) - :noindex: - - Increase/decrease the volume by step for the currently active output - - .. note:: For place-capable readers increment volume as long as card is on reader - - Default actions modifiers - **ignore_card_removal_action** |--| True - - **ignore_same_id_delay** |--| True - -.. py:function:: set_soft_max_volume(...) -> volume.ctrl.set_soft_max_volume(max_volume: int) - :noindex: - - Limit the maximum volume to max_volume for the currently active output - - Default actions modifiers - **ignore_card_removal_action** |--| True - -.. py:function:: toggle_output(...) -> volume.ctrl.toggle_output() - :noindex: - - Toggle the audio output sink - - Default actions modifiers - **ignore_card_removal_action** |--| True - -.. py:function:: shutdown(...) -> host.shutdown() - :noindex: - - Shutdown the host machine - - Default actions modifiers - **ignore_card_removal_action** |--| True - -.. py:function:: reboot(...) -> host.reboot() - :noindex: - - Reboot the host machine - - Default actions modifiers - **ignore_card_removal_action** |--| True - -.. py:function:: say_my_ip(...) -> host.say_my_ip(option='full') - :noindex: - - - - Default actions modifiers - **ignore_card_removal_action** |--| True - -.. py:function:: timer_shutdown(...) -> timers.timer_shutdown.start(wait_seconds=None) - :noindex: - - **Start the shutdown timer** - - Start the timer (with default or new parameters) - - Default actions modifiers - **ignore_card_removal_action** |--| True - -.. py:function:: timer_fade_volume(...) -> timers.timer_fade_volume.start(iterations=None, wait_seconds_per_iteration=None) - :noindex: - - **Start the volume fade out timer and shutdown** - - Start the timer (with default or new parameters) - - Default actions modifiers - **ignore_card_removal_action** |--| True - -.. py:function:: timer_stop_player(...) -> timers.timer_stop_player.start(wait_seconds=None) - :noindex: - - **Start the stop music timer** - - Start the timer (with default or new parameters) - - Default actions modifiers - **ignore_card_removal_action** |--| True - diff --git a/documentation/sphinx/userguide/rpc_command_reference.rst b/documentation/sphinx/userguide/rpc_command_reference.rst deleted file mode 100644 index e600ea336..000000000 --- a/documentation/sphinx/userguide/rpc_command_reference.rst +++ /dev/null @@ -1,994 +0,0 @@ -RPC Command Reference -*********************** - - -This file provides a summary of all the callable functions through the RPC. It depends on the loaded modules - -.. contents:: - -Module: publishing -------------------------------------------- - - -**loaded_from**: components.publishing - -Plugin interface for Jukebox Publisher - - -.. py:function:: publishing.republish(topic=None) - :noindex: - - Re-publish the topic tree 'topic' to all subscribers - - :param topic: Topic tree to republish. None = resend all - - -Module: volume -------------------------------------------- - - -**loaded_from**: components.volume - -PulseAudio Volume Control Plugin Package - - -.. py:function:: volume.ctrl.change_volume(step: int) - :noindex: - - Increase/decrease the volume by step for the currently active output - - -.. py:function:: volume.ctrl.get_mute() - :noindex: - - Return mute status for the currently active output - - -.. py:function:: volume.ctrl.get_outputs() - :noindex: - - Get current output and list of outputs - - -.. py:function:: volume.ctrl.get_soft_max_volume() - :noindex: - - Return the maximum volume limit for the currently active output - - -.. py:function:: volume.ctrl.get_volume() - :noindex: - - Get the volume - - -.. py:function:: volume.ctrl.mute(mute=True) - :noindex: - - Set mute status for the currently active output - - -.. py:function:: volume.ctrl.publish_outputs() - :noindex: - - Publish current output and list of outputs - - -.. py:function:: volume.ctrl.publish_volume() - :noindex: - - Publish (volume, mute) - - -.. py:function:: volume.ctrl.set_output(sink_index: int) - :noindex: - - Set the active output (sink_index = 0: primary, 1: secondary) - - -.. py:function:: volume.ctrl.set_soft_max_volume(max_volume: int) - :noindex: - - Limit the maximum volume to max_volume for the currently active output - - -.. py:function:: volume.ctrl.set_volume(volume: int) - :noindex: - - Set the volume (0-100) for the currently active output - - -.. py:function:: volume.ctrl.toggle_output() - :noindex: - - Toggle the audio output sink - - -Module: jingle -------------------------------------------- - - -**loaded_from**: components.jingle - -Jingle Playback Factory for extensible run-time support of various file types - - -.. py:function:: jingle.play(filename) - :noindex: - - Play the jingle using the configured jingle service - - Note: This runs in a separate thread. And this may cause troubles - when changing the volume level before - and after the sound playback: There is nothing to prevent another - thread from changing the volume and sink while playback happens - and afterwards we change the volume back to where it was before! - - There is no way around this dilemma except for not running the jingle as a - separate thread. Currently (as thread) even the RPC is started before the sound - is finished and the volume is reset to normal... - - However: Volume plugin is loaded before jingle and sets the default - volume. No interference here. It can now only happen - if (a) through the RPC or (b) some other plugin the volume is changed. Okay, now - (a) let's hope that there is enough delay in the user requesting a volume change - (b) let's hope no other plugin wants to do that - (c) no bluetooth device connects during this time (and pulseaudio control is set to toggle_on_connect) - and take our changes with the threaded approach. - - -.. py:function:: jingle.play_startup() - :noindex: - - Play the startup sound (using jingle.play) - - -.. py:function:: jingle.play_shutdown() - :noindex: - - Play the shutdown sound (using jingle.play) - - -Module: jingle.alsawave -------------------------------------------- - - -**loaded_from**: components.jingle.alsawave - -ALSA wave jingle Service for jingle.JingleFactory - - -.. py:function:: jingle.alsawave.alsawave.play(filename) - :noindex: - - Play the wave file - - -Module: jingle.jinglemp3 -------------------------------------------- - - -**loaded_from**: components.jingle.jinglemp3 - -Generic MP3 jingle Service for jingle.JingleFactory - - -.. py:function:: jingle.jinglemp3.jinglemp3.play(filename) - :noindex: - - Play the MP3 file - - -Module: player -------------------------------------------- - - -**loaded_from**: components.playermpd - -Package for interfacing with the MPD Music Player Daemon - - -.. py:function:: player.ctrl.get_current_song(param) - :noindex: - - - - -.. py:function:: player.ctrl.get_folder_content(folder: str) - :noindex: - - Get the folder content as content list with meta-information. Depth is always 1. - - Call repeatedly to descend in hierarchy - - :param folder: Folder path relative to music library path - - -.. py:function:: player.ctrl.get_player_type_and_version() - :noindex: - - - - -.. py:function:: player.ctrl.get_song_by_url(song_url) - :noindex: - - - - -.. py:function:: player.ctrl.list_albums() - :noindex: - - - - -.. py:function:: player.ctrl.list_all_dirs() - :noindex: - - - - -.. py:function:: player.ctrl.list_song_by_artist_and_album(albumartist, album) - :noindex: - - - - -.. py:function:: player.ctrl.map_filename_to_playlist_pos(filename) - :noindex: - - - - -.. py:function:: player.ctrl.move() - :noindex: - - - - -.. py:function:: player.ctrl.next() - :noindex: - - Play next track in current playlist - - -.. py:function:: player.ctrl.pause(state: int = 1) - :noindex: - - Enforce pause to state (1: pause, 0: resume) - - This is what you want as card removal action: pause the playback, so it can be resumed when card is placed - on the reader again. What happens on re-placement depends on configured second swipe option - - -.. py:function:: player.ctrl.play() - :noindex: - - - - -.. py:function:: player.ctrl.play_album(albumartist: str, album: str) - :noindex: - - Playback a album found in MPD database. - - All album songs are added to the playlist - The playlist is cleared first. - - :param albumartist: Artist of the Album provided by MPD database - :param album: Album name provided by MPD database - - -.. py:function:: player.ctrl.play_card(folder: str, recursive: bool = False) - :noindex: - - Main entry point for trigger music playing from RFID reader. Decodes second swipe options before playing folder content - - Checks for second (or multiple) trigger of the same folder and calls first swipe / second swipe action - accordingly. - - :param folder: Folder path relative to music library path - :param recursive: Add folder recursively - - -.. py:function:: player.ctrl.play_folder(folder: str, recursive: bool = False) -> None - :noindex: - - Playback a music folder. - - Folder content is added to the playlist as described by :mod:`jukebox.playlistgenerator`. - The playlist is cleared first. - - :param folder: Folder path relative to music library path - :param recursive: Add folder recursively - - -.. py:function:: player.ctrl.play_single(song_url) - :noindex: - - - - -.. py:function:: player.ctrl.playerstatus() - :noindex: - - - - -.. py:function:: player.ctrl.playlistinfo() - :noindex: - - - - -.. py:function:: player.ctrl.prev() - :noindex: - - - - -.. py:function:: player.ctrl.queue_load(folder) - :noindex: - - - - -.. py:function:: player.ctrl.remove() - :noindex: - - - - -.. py:function:: player.ctrl.repeatmode(mode) - :noindex: - - - - -.. py:function:: player.ctrl.replay() - :noindex: - - Re-start playing the last-played folder - - Will reset settings to folder config - - -.. py:function:: player.ctrl.replay_if_stopped() - :noindex: - - Re-start playing the last-played folder unless playlist is still playing - - .. note:: To me this seems much like the behaviour of play, - but we keep it as it is specifically implemented in box 2.X - - -.. py:function:: player.ctrl.resume() - :noindex: - - - - -.. py:function:: player.ctrl.rewind() - :noindex: - - Re-start current playlist from first track - - Note: Will not re-read folder config, but leave settings untouched - - -.. py:function:: player.ctrl.second_swipe_action() - :noindex: - - Toggle pause state, i.e. do a pause / resume depending on current state - - -.. py:function:: player.ctrl.seek(new_time) - :noindex: - - - - -.. py:function:: player.ctrl.shuffle(random) - :noindex: - - - - -.. py:function:: player.ctrl.stop() - :noindex: - - - - -.. py:function:: player.ctrl.toggle() - :noindex: - - Toggle pause state, i.e. do a pause / resume depending on current state - - -.. py:function:: player.ctrl.update() - :noindex: - - - - -Module: cards -------------------------------------------- - - -**loaded_from**: components.rfid.cards - -Handling the RFID card database - - -.. py:function:: cards.list_cards() - :noindex: - - Provide a summarized, decoded list of all card actions - - This is intended as basis for a formatter function - - Format: 'id': {decoded_function_call, ignore_same_id_delay, ignore_card_removal_action, description, from_alias} - - -.. py:function:: cards.delete_card(card_id: str, auto_save: bool = True) - :noindex: - - :param auto_save: - :param card_id: - - -.. py:function:: cards.register_card(card_id: str, cmd_alias: str, args: Union[List, NoneType] = None, kwargs: Union[Dict, NoneType] = None, ignore_card_removal_action: Union[bool, NoneType] = None, ignore_same_id_delay: Union[bool, NoneType] = None, overwrite: bool = False, auto_save: bool = True) - :noindex: - - Register a new card based on quick-selection - - If you are going to call this through the RPC it will get a little verbose - - **Example:** Registering a new card with ID *0009* for increment volume with a custom argument to inc_volume - (*here: 15*) and custom *ignore_same_id_delay value*:: - - plugin.call_ignore_errors('cards', 'register_card', - args=['0009', 'inc_volume'], - kwargs={'args': [15], 'ignore_same_id_delay': True, 'overwrite': True}) - - -.. py:function:: cards.register_card_custom() - :noindex: - - Register a new card with full RPC call specification (Not implemented yet) - - -.. py:function:: cards.load_card_database(filename) - :noindex: - - - - -.. py:function:: cards.save_card_database(filename=None, *, only_if_changed=True) - :noindex: - - Store the current card database. If filename is None, it is saved back to the file it was loaded from - - -Module: rfid -------------------------------------------- - - -**loaded_from**: components.rfid.reader - - - - -Module: timers -------------------------------------------- - - -**loaded_from**: components.timers - - - - -.. py:function:: timers.timer_shutdown.cancel() - :noindex: - - Cancel the timer - - -.. py:function:: timers.timer_shutdown.get_state() - :noindex: - - Get the current state and config as dictionary - - -.. py:function:: timers.timer_shutdown.get_timeout() - :noindex: - - Get the configured time-out - - :return: The total wait time. (Not the remaining wait time!) - - -.. py:function:: timers.timer_shutdown.is_alive() - :noindex: - - Check if timer is active - - -.. py:function:: timers.timer_shutdown.publish() - :noindex: - - Publish the current state and config - - -.. py:function:: timers.timer_shutdown.set_timeout(wait_seconds: float) - :noindex: - - Set a new time-out in seconds. Re-starts the timer if already running! - - -.. py:function:: timers.timer_shutdown.start(wait_seconds=None) - :noindex: - - Start the timer (with default or new parameters) - - -.. py:function:: timers.timer_shutdown.toggle() - :noindex: - - Toggle the activation of the timer - - -.. py:function:: timers.timer_shutdown.trigger() - :noindex: - - Trigger the next target execution before the time is up - - -.. py:function:: timers.timer_stop_player.cancel() - :noindex: - - Cancel the timer - - -.. py:function:: timers.timer_stop_player.get_state() - :noindex: - - Get the current state and config as dictionary - - -.. py:function:: timers.timer_stop_player.get_timeout() - :noindex: - - Get the configured time-out - - :return: The total wait time. (Not the remaining wait time!) - - -.. py:function:: timers.timer_stop_player.is_alive() - :noindex: - - Check if timer is active - - -.. py:function:: timers.timer_stop_player.publish() - :noindex: - - Publish the current state and config - - -.. py:function:: timers.timer_stop_player.set_timeout(wait_seconds: float) - :noindex: - - Set a new time-out in seconds. Re-starts the timer if already running! - - -.. py:function:: timers.timer_stop_player.start(wait_seconds=None) - :noindex: - - Start the timer (with default or new parameters) - - -.. py:function:: timers.timer_stop_player.toggle() - :noindex: - - Toggle the activation of the timer - - -.. py:function:: timers.timer_stop_player.trigger() - :noindex: - - Trigger the next target execution before the time is up - - -.. py:function:: timers.timer_fade_volume.cancel() - :noindex: - - Cancel the timer - - -.. py:function:: timers.timer_fade_volume.get_timeout() - :noindex: - - Get the configured time-out - - :return: The total wait time. (Not the remaining wait time!) - - -.. py:function:: timers.timer_fade_volume.is_alive() - :noindex: - - Check if timer is active - - -.. py:function:: timers.timer_fade_volume.publish() - :noindex: - - Publish the current state and config - - -.. py:function:: timers.timer_fade_volume.set_timeout(wait_seconds: float) - :noindex: - - Set a new time-out in seconds. Re-starts the timer if already running! - - -.. py:function:: timers.timer_fade_volume.start(iterations=None, wait_seconds_per_iteration=None) - :noindex: - - Start the timer (with default or new parameters) - - -.. py:function:: timers.timer_fade_volume.toggle() - :noindex: - - Toggle the activation of the timer - - -.. py:function:: timers.timer_fade_volume.trigger() - :noindex: - - Trigger the next target execution before the time is up - - -Module: host -------------------------------------------- - - -**loaded_from**: components.hostif.linux - - - - -.. py:function:: host.shutdown() - :noindex: - - Shutdown the host machine - - -.. py:function:: host.reboot() - :noindex: - - Reboot the host machine - - -.. py:function:: host.jukebox_is_service() - :noindex: - - Check if current Jukebox process is running as a service - - -.. py:function:: host.is_any_jukebox_service_active() - :noindex: - - Check if a Jukebox service is running - - .. note:: Does not have the be the current app, that is running as a service! - - -.. py:function:: host.restart_service() - :noindex: - - Restart Jukebox App if running as a service - - -.. py:function:: host.get_disk_usage(path='/') - :noindex: - - Return the disk usage in Megabytes as dictionary for RPC export - - -.. py:function:: host.get_cpu_temperature() - :noindex: - - Get the CPU temperature with single decimal point - - No error handling: this is expected to take place up-level! - - -.. py:function:: host.publish_cpu_temperature() - :noindex: - - - - -.. py:function:: host.get_ip_address() - :noindex: - - Get the IP address - - -.. py:function:: host.say_my_ip(option='full') - :noindex: - - - - -.. py:function:: host.wlan_disable_power_down(card=None) - :noindex: - - Turn off power management of wlan. Keep RPi reachable via WLAN - - This must be done after every reboot - card=None takes card from configuration file - - -.. py:function:: host.get_autohotspot_status() - :noindex: - - Get the status of the auto hotspot feature - - -.. py:function:: host.stop_autohotspot() - :noindex: - - Stop auto hotspot functionality - - Basically disabling the cronjob and running the script one last time manually - - -.. py:function:: host.start_autohotspot() - :noindex: - - start auto hotspot functionality - - Basically enabling the cronjob and running the script one time manually - - -.. py:function:: host.timer_temperature.cancel() - :noindex: - - Cancel the timer - - -.. py:function:: host.timer_temperature.get_timeout() - :noindex: - - Get the configured time-out - - :return: The total wait time. (Not the remaining wait time!) - - -.. py:function:: host.timer_temperature.is_alive() - :noindex: - - Check if timer is active - - -.. py:function:: host.timer_temperature.publish() - :noindex: - - Publish the current state and config - - -.. py:function:: host.timer_temperature.set_timeout(wait_seconds: float) - :noindex: - - Set a new time-out in seconds. Re-starts the timer if already running! - - -.. py:function:: host.timer_temperature.start(wait_seconds=None) - :noindex: - - Start the timer (with default or new parameters) - - -.. py:function:: host.timer_temperature.toggle() - :noindex: - - Toggle the activation of the timer - - -.. py:function:: host.timer_temperature.trigger() - :noindex: - - Trigger the next target execution before the time is up - - -Module: bluetooth_audio_buttons -------------------------------------------- - - -**loaded_from**: components.controls.bluetooth_audio_buttons - -Plugin to attempt to automatically listen to it's buttons (play, next, ...) -when a bluetooth sound device (headphone, speakers) connects - - -.. py:function:: bluetooth_audio_buttons.activate(device_name: str, exact: bool = True, open_initial_delay: float = 0.25) - :noindex: - - - - -Module: gpio -------------------------------------------- - - -**loaded_from**: components.gpio.gpioz.plugin - -The GPIOZ plugin interface build all input and output devices from the configuration file and connects -the actions and callbacks. It also provides a very restricted, but common API for the output devices to the RPC. -That API is mainly used for testing. All the relevant output state changes are usually made through callbacks directly -using the output device's API. - - -.. py:function:: gpio.on(name: str) - :noindex: - - Turn an output device on - - :param name: The alias name output device instance - - -.. py:function:: gpio.off(name: str) - :noindex: - - Turn an output device off - - :param name: The alias name output device instance - - -.. py:function:: gpio.set_value(name: str, value: Any) - :noindex: - - Set the output device to :attr:`value` - - :param name: The alias name output device instance - - :param value: Value to set the device to - - -.. py:function:: gpio.flash(name, on_time=1, off_time=1, n=1, *, fade_in_time=0, fade_out_time=0, tone=None, color=(1, 1, 1)) - :noindex: - - Flash (blink or beep) an output device - - This is a generic function for all types of output devices. Parameters not applicable to an - specific output device are silently ignored - - :param name: The alias name output device instance - - :param on_time: Time in seconds in state ``ON`` - - :param off_time: Time in seconds in state ``OFF`` - - :param n: Number of flash cycles - - :param tone: The tone in to play, e.g. 'A4'. *Only for TonalBuzzer*. - - :param color: The RGB color *only for PWMLED*. - - :param fade_in_time: Time in seconds for transitioning to on. *Only for PWMLED and RGBLED* - - :param fade_out_time: Time in seconds for transitioning to off. *Only for PWMLED and RGBLED* - - -Module: music_cover_art -------------------------------------------- - - -**loaded_from**: components.music_cover_art - -Read all cover art from music save it to a cache for the UI to load - - -.. py:function:: music_cover_art.ctrl.get_by_filename_as_base64(audio_src: str) - :noindex: - - - - -Module: misc -------------------------------------------- - - -**loaded_from**: components.misc - -Miscellaneous function package - - -.. py:function:: misc.rpc_cmd_help() - :noindex: - - Return all commands for RPC - - -.. py:function:: misc.get_all_loaded_packages() - :noindex: - - Get all successfully loaded plugins - - -.. py:function:: misc.get_all_failed_packages() - :noindex: - - Get all plugins with error during load or initialization - - -.. py:function:: misc.get_start_time() - :noindex: - - Time when JukeBox has been started - - -.. py:function:: misc.get_log_debug() - :noindex: - - Get the log file (from the debug_file_handler) - - -.. py:function:: misc.get_log_error() - :noindex: - - Get the log file (from the error_file_handler) - - -.. py:function:: misc.get_version() - :noindex: - - - - -.. py:function:: misc.get_git_state() - :noindex: - - Return git state information for the current branch - - -.. py:function:: misc.empty_rpc_call(msg: str = '') - :noindex: - - This function does nothing. - - The RPC command alias 'none' is mapped to this function. - - This is also used when configuration errors lead to non existing RPC command alias definitions. - When the alias definition is void, we still want to return a valid function to simplify error handling - up the module call stack. - - :param msg: If present, this message is send to the logger with severity warning - - - - -Generation notes -------------------------------------------- - - -This is an automatically generated file from the loaded plugins: - -* *publishing*: components.publishing -* *volume*: components.volume -* *jingle*: components.jingle -* *jingle.alsawave*: components.jingle.alsawave -* *jingle.jinglemp3*: components.jingle.jinglemp3 -* *player*: components.playermpd -* *cards*: components.rfid.cards -* *rfid*: components.rfid.reader -* *timers*: components.timers -* *host*: components.hostif.linux -* *bluetooth_audio_buttons*: components.controls.bluetooth_audio_buttons -* *gpio*: components.gpio.gpioz.plugin -* *music_cover_art*: components.music_cover_art -* *misc*: components.misc diff --git a/documentation/sphinx/userguide/rpc_commands.rst b/documentation/sphinx/userguide/rpc_commands.rst deleted file mode 100644 index 5b2a58515..000000000 --- a/documentation/sphinx/userguide/rpc_commands.rst +++ /dev/null @@ -1,116 +0,0 @@ -RPC Commands -***************** - -We use the RPC commands when triggering actions from different inputs like a card swipe, -a GPIO button press, etc. Triggering an action is equal to sending an RPC function call. -In many places the command to send when an input is triggered is configurable in a YAML-file. - -Basics ---------- - -Consequently, you need to know how to specify the RPC command in the YAML file. -Here is the essence of what you need to know: - -An RPC command consists of up to three parts - - #. the function to execute (e.g. play_folder, change_volume) - #. the positional arguments (optional) - #. the keyword arguments (optional) - -The function specification consists of two (e.g., ``host.shutdown``) or three terms (e.g., ``volume.ctrl.change_volume``). -In configuration files, this will look like this: - -.. code-block:: yaml - - package: host - plugin: shutdown - -Or like this for a three part function with the argument set to ``5``: - -.. code-block:: yaml - - package: volume - plugin: ctrl - method: change_volume - args: [5] - -The keyword ``method`` is optional. If needs to be used depends on the function you want to call. -You will find a full list of RPC callable functions in :ref:`userguide/rpc_command_reference:RPC Command Reference`, - -Aliases --------- - -Not so complicated, right? It will get even easier. For common commands we have defined aliases. An alias simply maps -to a pre-defined RPC command, e.g. ``play_card`` maps to ``player.ctrl.play_card``. - -Instead of - -.. code-block:: yaml - - package: player - plugin: ctrl - method: play_card - args: [path/to/folder] - -you can simply specify instead : - -.. code-block:: yaml - - alias: play_card - args: [path/to/folder] - -Using in alias is optional. But if the keyword is present in the configuration it takes precedence over an explicit -specified RPC command. All alias definitions may be found -in the :ref:`userguide/rpc_command_alias_reference:RPC Command Alias Reference`. - -Arguments --------------- - -Arguments can be specified in similar fashion to Python function arguments: as positional arguments and / or -keyword arguments. Let's check out play_card, which is defined as: - -.. py:function:: play_card(...) -> player.ctrl.play_card(folder: str, recursive: bool = False) - :noindex: - - :param folder: Folder path relative to music library path - :param recursive: Add folder recursively - -This means it takes two arguments: - - * folder of type string - * recursive of type bool - -In the following examples, we will always use the alias for smaller configuration text. All three examples -do exactly the same, but use different ways of specifying the command. - -.. code-block:: yaml - - alias: play_card - args: [path/to/folder, True] - -.. code-block:: yaml - - alias: play_card - args: [path/to/folder] - kwargs: - recursive: True - -.. code-block:: yaml - - alias: play_card - kwargs: - folder: path/to/folder - recursive: True - - -.. important:: *args* must be a **list** of arguments to be passed! Even if only a single argument is passed. - So, use *args: [value]*. We try catch mis-uses but that might not always work. - - -You will find some more examples the configuration of the :ref:`userguide/carddatabase:Card Database` - -For developers ----------------- - -There is a ready-to-use decoding functions which decodes an RPC command (with or without alias) -from a YAML entry:func:`jukebox.utils.decode_rpc_command`. diff --git a/documentation/sphinx/userguide/sync_rfidcards.rst b/documentation/sphinx/userguide/sync_rfidcards.rst deleted file mode 100644 index 5cb554acb..000000000 --- a/documentation/sphinx/userguide/sync_rfidcards.rst +++ /dev/null @@ -1,71 +0,0 @@ -Syncronisation RFID Cards -************************* - -This component handles the synchronisation of RFID cards (audiofolder and card database entries). - -It allows to manage card database entries and audiofiles of one to many Phonieboxes -in a central place (e.g. NAS, primary Phoniebox etc.) in the network, -but allows to play the audio offline once the data has synced. -The synchronisation can be initiated with the command ``sync-all`` -and optionally on every RFID scan for a particular CardID and its corresponding audiofolder. -To execute the ``sync-all`` command, bind a RFID card to the command. -For the "RFID scan sync" feature, activate the option in the configuration -or bind a RFID card to the command for dynamic activation or deactivation. - -Synchronisation ---------------- - -The synchronisation will be FROM a server TO the Phoniebox, overriding existing files. -A local configuration will be lost after the synchronization. -If you want to make the initial setup e.g. via WebUi copy the files and use it as a base for the server. - -To access the files on the server, 2 modes are supported: SSH or MOUNT. -Please make sure you have the correct access rights to the source and use key-based authentication for SSH. - -RFID scan sync -^^^^^^^^^^^^^^ -If the feature "RFID scan sync" is activated, there will be a check on every RFID scan against the server -if a matching card entry and audiofolder is available. If so, changes will be synced. -The playback will be delayed for the time the data is transfered (see "sync-all" to use a full synchronization if a lot of new files have been added). -If the server is not reachable, the check will be aborted after the timeout. -Therfore, an unreachable server will cause a delay (see commands to toggle activation state). -Deleted card entries / audiofolders (not the contained items) will not be purged locally if deleted on remote. -This is also true for changed card entries (the old audiofolder / -files will remain). To remove not existing items us a "sync-all". - -Configuration -------------- - -Set the corresponding setting in ``shared\settings\jukebox.yaml`` to activate this feature. - -.. code-block:: yaml - - modules: - named: - ... - sync_rfidcards: synchronisation.rfidcards - - ... - sync_rfidcards: - enable: false - config_file: ../../shared/settings/sync_rfidcards.yaml - -The settings file (``shared\settings\sync_rfidcards.yaml``) contains the following configuration - -.. code-block:: yaml - - sync_rfidcards: - # Holds the activation state of the optional feature "RFID scan sync". Values are "TRUE" or "FALSE" - on_rfid_scan_enabled: true # bool - # Server Access mode. MOUNT or SSH - mode: mount # 'mount' or 'ssh' - credentials: - # IP or hostname of the server (used to check connectivity and for SSH mode). e.g. "192.168.0.2" or "myhomeserver.local" - server: '' - # Port (used to check connectivity and for SSH mode). e.g. "80" or "22" - port: # int - # Timeout to reach the server (in seconds) (used to check connectivity). e.g. 1 - timeout: 1 # int - # Path to the shared files to sync (without trailing slash) (remote path for SSH mode or local path for MOUNT mode). e.g. "/mnt/Phoniebox" - path: '' - # Username if SSH mode is used. - username: '' diff --git a/documentation/sphinx/userguide/system.rst b/documentation/sphinx/userguide/system.rst deleted file mode 100644 index 3740663ab..000000000 --- a/documentation/sphinx/userguide/system.rst +++ /dev/null @@ -1,121 +0,0 @@ -System Setup -===================== - -A few words on how the system is setup and interacts. - -The system consists of - - #. the :ref:`userguide/system:Music Player Daemon (MPD)` which we use for all music playback (local, stream, podcast, ...) - #. the :ref:`userguide/system:PulseAudio` for flexible audio output support - #. the :ref:`userguide/system:Jukebox Core Service` for controlling MPD and PulseAudio and providing all the features - #. the :ref:`userguide/system:Web UI` which is served through an Nginx web server - #. a set of :ref:`developer/coreapps:Configuration Tools` and - a set of :ref:`developer/coreapps:Developer Tools` - -.. note:: The default install puts everything into the folder ``/home/pi/RPi-Jukebox-RFID``. - Another folder might work, but is certainly not tested. Things are installed for the default user ``pi``. Again, - another user might work, but is not tested. - -Music Player Daemon (MPD) --------------------------- - -The Music Player Daemon runs as *user-local* service (not as system-wide service which is usually the default). -This is important for the interaction with PulseAudio. - -You will find the MPD configuration file under - -.. code-block:: text - - $HOME/.config/mpd/mpd.conf - -All MPD *var*-files are also located in ``$HOME/.config/mpd``. - -The service can be controlled with the *systemctl*-command when adding the parameter ``--user``: - -.. code-block:: bash - - $ systemctl --user status mpd - $ systemctl --user start mpd - $ systemctl --user stop mpd - -.. important:: Never start or enable the system-wide MPD service with `sudo systemctl start mpd`! - -To check if MPD is running or has issues, use - -.. code-block:: bash - - $ systemctl --user status mpd - # or, if you need to get the full logs - $ journalctl --user -b -u mpd - -The ``systemd`` service file is located at the default location for user services: - -.. code-block:: text - - /usr/lib/systemd/user/mpd.service - -PulseAudio ---------------------- - -We use PulseAudio for the audio output configuration. Check out the Audio Configuration page for details. - -There is a number of reasons for that: - - * It is easier to support and setup different audio hardware. Over the years, many builders have - tried many different ways to set up audio on their Jukebox so this become the most reliable and compatible - solution - * We can cleanly control and switch between different audio outputs independent of the playback software - * The current Pi OS based on Bullseye does not allow another way to control Bluetooth based speakers, - as Bluealsa is currently not working with Bluez 5 - -The PulseAudio configuration file is located at - -.. code-block:: text - - ~/.config/pulse/default.pa - -Service control and service configuration file location is identical to MPD. - -Jukebox Core Service ---------------------- - -The :ref:`developer/coreapps:Jukebox Core` runs as a *user-local* service with the name ``jukebox-daemon``. -Similar to MPD, it's important that it does run as system-wide service to be able to interact with PulseAudio. - -The service can be controlled with the ``systemctl``-command by adding the parameter ``--user`` - -.. code-block:: bash - - $ systemctl --user start jukebox-daemon - $ systemctl --user stop jukebox-daemon - -Check out the service with - -.. code-block:: bash - - $ systemctl --user status jukebox-daemon - # and if you need to get the full log output - $ journalctl --user -b -u jukebox-daemon - -The ``systemd`` service file is located at the default location for user services: - -.. code-block:: text - - /usr/lib/systemd/user/jukebox-daemon.service - -Starting and stopping the service can be useful for debugging or configuration checks. - -Web UI ------------------------ - -The Web UI is served using nginx. Nginx runs as a system service. The home directory is localed at - -.. code-block:: text - - /home/pi/RPi-Jukebox-RFID/src/webapp/build - -The Nginx configuration is located at - -.. code-block:: text - - /etc/nginx/sites-available/default diff --git a/documentation/sphinx/userguide/troubleshooting.rst b/documentation/sphinx/userguide/troubleshooting.rst deleted file mode 100644 index 24d1fec9c..000000000 --- a/documentation/sphinx/userguide/troubleshooting.rst +++ /dev/null @@ -1,107 +0,0 @@ -Troubleshooting -***************** - -We have made a point of providing extensive log messages. -In full debug mode, this may become very verbose. In fact, better observability -has been one of the design goals for version 3. - -There are various options to get access to debug information. - -Debugging your setup runs in several steps - - #. Check that :ref:`audio output works` - #. Check that :ref:`MPD works` - #. Checking log messages from the Jukebox Core App as described below - -The short answer ----------------- - -**We are still in the Pre-Release phase, so by default two log files should be written out:** - -.. code-block:: bash - - ../shared/logs/app.log : Complete Debug Messages - ../shared/logs/errors.log: Only Errors and Warnings - -These files always contain the messages of the current run only. -The logs of previous runs are post-fixed with ``.1``, e.g. ``app.log.1``. This is useful for debugging issues during -shutdown of the service. - -The logs are also available via the Web Server: - -.. code-block:: - - http://ip.of.your.box/logs - -.. important:: Always check the time modification date or the beginning of the log - file to ensure you are not looking at an old log file! - -The long answer: A few more details ------------------------------------- - -If started without parameters, the Jukebox checks for the existence of ``../shared/settings/logger.yaml`` -and if present, uses that configuration for logging. This file is created by the installation process. -The default configuration file is also provided in ``../resources/default-settings/logger.default.yaml``. -We use Python's logging module to provide the debug messages which is configured through this file. - -**We are still in the Pre-Release phase which means full debug logging is enabled by default.** - -Default logging configuration -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -The default logging config does 2 things: - -1. It writes 2 log files: - -.. code-block:: bash - - ../shared/logs/app.log : Complete Debug Messages - ../shared/logs/errors.log : Only Errors and Warnings - -2. Prints logging messages to the console. If run as a service, only error messages are emitted to console to avoid spamming the system log files. - -Debug logging in console -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -For debugging, it is usually very helpful to observe the apps output directly -on the console log. - -.. code-block:: bash - - # Make sure the Jukebox service is stopped: - $ systemctl --user stop jukebox-daemon - - # Start the Jukebox in debug mode: - # with default logger: - $ ./run_jukebox.py - - # or with custom logger configuration: - $ ./run_jukebox.py --logger ../path/to/logger.yaml - -Fallback configuration -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -It is possible to start the Jukebox with a catch-all debug enabler with a logger.yaml. -Attention: This only emits messages to the console and does not write to the log files! -This is more a fallback features: - -.. code-block:: bash - - $./run_jukebox.py -vv - -Extreme cases -^^^^^^^^^^^^^ - -Sometimes, the Jukebox app might crash with an exception and stack trace which is -neither logged, nor caught and handled. - -If run locally from your console, you will see it immediately. No worries! - -If running as a service, you will probably not even notice immediately that something has -gone pear-shaped. Services are restarted automatically when they fail. - -Things are just not behaving as expected? Time to check the system logs: - -.. code-block:: bash - - $journalctl --user -b -u jukebox-daemon