diff --git a/.flake8 b/.flake8
index d1b156813..a3c0629ce 100644
--- a/.flake8
+++ b/.flake8
@@ -1,12 +1,33 @@
[flake8]
-max-line-length = 120
+max-line-length = 127
ignore =
+ # continuation line over-indented for hanging indent
+ E126,
# continuation line over-indented for visual indent
E127,
# continuation line under-indented for visual indent
- E128
+ E128,
+ # line break before binary operator
+ W503,
+ # We don't always want periods at the end of the first docstring line
+ D400,
+ # We dont rephrase to imperative mood
+ D401
per-file-ignores =
# Only in __init__files ignore imported but unused
# Not necessary, if __all__ is declared in __init__ file
# https://www.python.org/dev/peps/pep-0008/#id48
- __init__.py:F401
+ __init__.py:F401,
+ components/smart-home-automation/MQTT-protocol/daemon_mqtt_client.py:W605,
+ components/controls/buttons_usb_encoder/*.py:E402
+count = True
+max-complexity = 12
+statistics = True
+show-source = True
+filename = *.py,*.py.*
+extend-exclude =
+ # Ignore dirs and files, which are from external sources
+ components/displays/HD44780-i2c/
+ scripts/Reader.py.pcsc
+ # Ignore helper scripts
+ scripts/helperscripts/
diff --git a/.github/workflows/markdown.yml b/.github/workflows/markdown.yml
new file mode 100644
index 000000000..68b53005f
--- /dev/null
+++ b/.github/workflows/markdown.yml
@@ -0,0 +1,29 @@
+name: Markdown Linting
+
+on:
+ push:
+ branches-ignore:
+ - 'future3/**'
+ paths:
+ - '**.md'
+ pull_request:
+ branches:
+ - develop
+ - master
+ paths:
+ - '**.md'
+
+jobs:
+ build:
+
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v4
+
+ - name: Linting markdown
+ uses: DavidAnson/markdownlint-cli2-action@v17
+ with:
+ config: .markdownlint-cli2.yaml
+ #continue-on-error: true
diff --git a/.github/workflows/pythonpackage.yml b/.github/workflows/pythonpackage.yml
index 6cb871112..b7eab32ef 100644
--- a/.github/workflows/pythonpackage.yml
+++ b/.github/workflows/pythonpackage.yml
@@ -30,13 +30,12 @@ jobs:
pip install spidev
pip install -r requirements.txt
pip install -r requirements-GPIO.txt
+ - name: Setup flake8 annotations
+ uses: rbialon/flake8-annotations@v1
- name: Lint with flake8
run: |
pip install flake8
- # stop the build if there are Python syntax errors or undefined names
- flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics --filename=*.py,*.py.*
- # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide
- flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics --filename=*.py,*.py.*
+ flake8 --config .flake8
- name: Test with pytest
run: |
pytest --cov --cov-config=.coveragerc --cov-report xml
diff --git a/.github/workflows/test_docker_debian_codename_sub.yml b/.github/workflows/test_docker_debian_codename_sub.yml
index 00ef4efd7..369d016ea 100644
--- a/.github/workflows/test_docker_debian_codename_sub.yml
+++ b/.github/workflows/test_docker_debian_codename_sub.yml
@@ -55,10 +55,10 @@ jobs:
- uses: actions/checkout@v4
- name: Set up QEMU
- uses: docker/setup-qemu-action@v3.0.0
+ uses: docker/setup-qemu-action@v3.2.0
- name: Set up Docker Buildx
- uses: docker/setup-buildx-action@v3.2.0
+ uses: docker/setup-buildx-action@v3.7.1
with:
# network=host driver-opt needed to push to local registry
driver-opts: network=host
@@ -94,7 +94,7 @@ jobs:
# Build base image for debian version name. Layers will be cached and image pushes to local registry
- name: Build Image - Base
- uses: docker/build-push-action@v5
+ uses: docker/build-push-action@v6
with:
context: .
load: false
@@ -112,7 +112,7 @@ jobs:
# Build new image with updates packages based on base image. Layers will NOT be chached. Result is written to file.
- name: Build Image - Update
- uses: docker/build-push-action@v5
+ uses: docker/build-push-action@v6
with:
context: .
load: false
@@ -152,10 +152,10 @@ jobs:
steps:
- name: Set up QEMU
- uses: docker/setup-qemu-action@v3.0.0
+ uses: docker/setup-qemu-action@v3.2.0
- name: Set up Docker Buildx
- uses: docker/setup-buildx-action@v3.2.0
+ uses: docker/setup-buildx-action@v3.7.1
- name: Artifact Download Docker Image
uses: actions/download-artifact@v4
diff --git a/.markdownlint-cli2.yaml b/.markdownlint-cli2.yaml
new file mode 100644
index 000000000..4e30f537c
--- /dev/null
+++ b/.markdownlint-cli2.yaml
@@ -0,0 +1,56 @@
+#
+# markdownlint-cli2 configuration, see https://github.com/DavidAnson/markdownlint-cli2?tab=readme-ov-file#configuration
+#
+
+# rules, see https://github.com/DavidAnson/markdownlint/blob/main/doc/Rules.md
+config:
+ line-length: false
+ # ignore dollar signs
+ commands-show-output: false
+ no-trailing-punctuation: false
+ no-duplicate-heading:
+ siblings_only: true
+ # allow some tags we use for formatting
+ no-inline-html:
+ allowed_elements: [ "details", "summary" ]
+
+# Include a custom rule package
+#customRules:
+# - markdownlint-rule-titlecase
+
+# Fix no fixable errors
+fix: false
+
+# Define a custom front matter pattern
+#frontMatter: "
[^]*<\/head>"
+
+# Define glob expressions to use (only valid at root)
+globs:
+ - "**.md"
+
+# Define glob expressions to ignore
+ignores:
+ - "htdocs/**"
+
+# Use a plugin to recognize math
+#markdownItPlugins:
+# -
+# - "@iktakahiro/markdown-it-katex"
+
+# Additional paths to resolve module locations from
+#modulePaths:
+# - "./modules"
+
+# Enable inline config comments
+noInlineConfig: false
+
+# Disable progress on stdout (only valid at root)
+noProgress: true
+
+# Use a specific formatter (only valid at root)
+#outputFormatters:
+# -
+# - markdownlint-cli2-formatter-default
+
+# Show found files on stdout (only valid at root)
+showFound: true
\ No newline at end of file
diff --git a/README.md b/README.md
index ebaada654..3b615efb8 100644
--- a/README.md
+++ b/README.md
@@ -19,7 +19,7 @@ Phoniebox is a contactless jukebox for the Raspberry Pi, playing audio files, pl
Another bunch of wonderful designs!
-To share your design or see all previous calendars and designs of the community visit the [Phoniebox Gallery](https://github.com/MiczFlor/RPi-Jukebox-RFID/wiki/GALLERY).
+To share your design or see all previous calendars and designs of the community visit the [Phoniebox Gallery](https://github.com/MiczFlor/RPi-Jukebox-RFID/wiki/GALLERY).
![The Phoniebox Calendar](https://raw.githubusercontent.com/wiki/MiczFlor/RPi-Jukebox-RFID/img/gallery/calendar/latest-Phoniebox-Calendar.jpg "The Phoniebox Calendar")
@@ -141,7 +141,8 @@ There is a growing section of [troubleshooting](https://github.com/MiczFlor/RPi-
Here is a list of equipment needed. You can find a lot second hand online (save money and the planet). The links below lead to Amazon, not at all because I want to support them, but because their PartnerNet program helps to support the Phoniebox maintenance (a little bit...).
-Note: depending on individual projects, the hardware requirements vary.
+> [!NOTE]
+> Depending on individual projects, the hardware requirements vary.
### Raspberry Pi
@@ -189,6 +190,8 @@ These are links to additional items, which will add an individual flavour to you
Special hardware is now organised in the folder [`components`](components/). If you have new hardware attached to your Phoniebox, please add to this library! It currently contains soundcards, displays, GPIO controls, RFID reader, smarthome integration.
## Support Phoniebox
+
+
@@ -211,6 +214,8 @@ See the Phoniebox code in action, watch this video and read the blog post from [
A new video screencast about
+
+
**What makes this Phoniebox easy to install and use:**
* Runs on all Raspberry Pi models (1, 2, 3 and 4) and [Raspberry Zero](https://github.com/MiczFlor/RPi-Jukebox-RFID/issues/15).
@@ -243,7 +248,6 @@ See innovation, upcycling and creativity in the [Phoniebox Gallery](https://gith
![Caption](https://raw.githubusercontent.com/wiki/MiczFlor/RPi-Jukebox-RFID/img/gallery/KingKahn-20180101-Jukebox-01-h90.jpg)
![Caption](https://raw.githubusercontent.com/wiki/MiczFlor/RPi-Jukebox-RFID/img/gallery/hailogugo-20171222-h90-01.jpg)
-
## Sustainability
You might be surprised how easy and affordable you can get a RaspberryPi or an "appropriate" housing for your Phoniebox **second hand**. Think about the planet before you buy a new one.
diff --git a/ci/Dockerfile.debian b/ci/Dockerfile.debian
index 45c44d350..f6dcf8ed6 100644
--- a/ci/Dockerfile.debian
+++ b/ci/Dockerfile.debian
@@ -1,7 +1,7 @@
# Base Target to build and install all needed base configuration and packages. Specifie the needed platform with the docker '--platform XXX' option
ARG DEBIAN_CODENAME=bullseye
ARG BASE_TEST_IMAGE=test-code
-FROM debian:${DEBIAN_CODENAME}-slim as base
+FROM debian:${DEBIAN_CODENAME}-slim AS base
ARG DEBIAN_CODENAME
ENV DOCKER_RUNNING=true
@@ -34,7 +34,7 @@ RUN export DEBIAN_FRONTEND=noninteractive \
# ------
# Base Target for setting up the default user. user can be selected with the docker '--user YYY' option
-FROM base as user
+FROM base AS user
ARG USER=pi
ARG USER_GROUP=$USER
@@ -50,7 +50,7 @@ RUN groupadd --gid 1000 $USER_GROUP \
####### Code Targets #######
# Target for adding code from the repo. Set Default User
-FROM user as code
+FROM user AS code
COPY --chown=$USER:$USER_GROUP --chmod=770 . /code
WORKDIR /code
@@ -63,7 +63,7 @@ USER $USER
####### Test Targets #######
# Target for setting up an alternativ user 'hans:wurst'. user can be selected with the docker '--user YYY' option
-FROM user as test-user
+FROM user AS test-user
ENV TEST_USER_GROUP=test
@@ -79,7 +79,7 @@ RUN export USER_ALT=hans \
# Target for adding envs and scripts from the repo to test installation
-FROM test-user as test-code
+FROM test-user AS test-code
ARG GIT_BRANCH
ARG GIT_URL
@@ -104,7 +104,7 @@ COPY --chown=root:$TEST_USER_GROUP --chmod=770 scripts/installscripts/tests/*.sh
# Target for applying latest updates (should not be cached!)
-FROM $BASE_TEST_IMAGE as test-update
+FROM $BASE_TEST_IMAGE AS test-update
RUN export DEBIAN_FRONTEND=noninteractive \
&& apt-get update \
&& apt-get -y upgrade \
diff --git a/ci/README.md b/ci/README.md
index 674dedd64..b522afb4f 100644
--- a/ci/README.md
+++ b/ci/README.md
@@ -11,35 +11,42 @@ This is a work in progress so expect things to fail or being flaky.
* Flash its sd card with **Raspberry Pi OS lite**
* use raspi-config to resize the filesystem to the whole sd card (menu: 7 -> A1)
* install some tools and reboot:
-```bash
+
+ ```bash
sudo apt-get update
sudo apt-get -y dist-upgrade
sudo apt-get -y install docker.io git
sudo gpasswd -a pi docker
sudo reboot
-```
+ ```
+
* login to your RPi
* clone the repo and cd into its local clone:
-```bash
+
+ ```bash
cd /home/pi/
# optional: change to your fork appropriately
git clone https://github.com/MiczFlor/RPi-Jukebox-RFID.git
cd RPi-Jukebox-RFID/
# optional: switch to another branch
git checkout
-```
+ ```
+
* build the docker image:
+
```bash
docker build -t rpi-jukebox-rfid:debian-latest -f ci/Dockerfile.debian --platform=linux/arm/v7 --target=code .
```
- * additional arguments
- * for builds
- - on normal PCs use `--platform=linux/amd64`
- - on a raspberry pi use `--platform=linux/arm/v7`
- * to use a different debian version as base add parameter `--build-arg="DEBIAN_CODENAME="` ( = e.g. buster, bullseye, ...).
+
+ * additional arguments
+ * for builds
+ * on normal PCs use `--platform=linux/amd64`
+ * on a raspberry pi use `--platform=linux/arm/v7`
+ * to use a different debian version as base add parameter `--build-arg="DEBIAN_CODENAME="` ( = e.g. buster, bullseye, ...).
* get something to drink or eat
* run the freshly built docker image and start testing. For example:
+
```bash
docker run --rm -ti rpi-jukebox-rfid:debian-latest /bin/bash
cd /home/pi/
@@ -48,12 +55,14 @@ This is a work in progress so expect things to fail or being flaky.
bash GIT_URL=https://github.com/MiczFlor/RPi-Jukebox-RFID.git GIT_BRANCH=main install-jukebox.sh
```
- NOTE: Get familiar with docker and its flags - `--rm` for example will remove the
- container after you log out of it and all changes will be lost.
+ > [!NOTE]
+ > Get familiar with docker and its flags - `--rm` for
+ > example will remove the
+ > container after you log out of it and all changes will be lost.
### mount hosts code as volume
-The created image now contains all the code in the directory `/code` - if you do not want to rebuild the image after each code-change you can 'mount' the RPi's code version into the container.
+The created image now contains all the code in the directory `/code` - if you do not want to rebuild the image after each code-change you can 'mount' the RPi's code version into the container.
Add `-w /code -v $PWD:/code` to the `docker run` parameter.
In that way every change to the code in the container will be available on the RPi as well as vice versa.
diff --git a/components/bluetooth-sink-switch/bt-sink-switch.py b/components/bluetooth-sink-switch/bt-sink-switch.py
index a107703a7..7fe2d918f 100755
--- a/components/bluetooth-sink-switch/bt-sink-switch.py
+++ b/components/bluetooth-sink-switch/bt-sink-switch.py
@@ -47,13 +47,15 @@ def bt_check_mpc_err() -> None:
logger.debug(mpcplay)
-def bt_switch(cmd, led_pin=None):
+def bt_switch(cmd, led_pin=None): # noqa C901
"""
- Set/Toggle between regular speakers and headphone output. If no bluetooth device is connected, always defaults to mpc output 1
+ Set/Toggle between regular speakers and headphone output. If no bluetooth device is connected,
+ always defaults to mpc output 1
To be precise: toggle between mpc output 1 and mpc output 2.
- So, set up your /etc/mpd.conf correctly: first audio_output section should be speakers, second audio_output section should be headphones
+ So, set up your /etc/mpd.conf correctly: first audio_output section should be speakers,
+ second audio_output section should be headphones
To set up bluetooth headphones, follow the wiki
Short guide to connect bluetooth (without audio setup)
sudo bluetoothctl
@@ -71,13 +73,16 @@ def bt_switch(cmd, led_pin=None):
sudo apt install bluetooth
Attention
- The user to runs this script (precisly who runs bluetoothctl) needs proper access rights. Otherwise bluetoothctl will always return "no default controller found"
+ The user to runs this script (precisly who runs bluetoothctl) needs proper access rights.
+ Otherwise bluetoothctl will always return "no default controller found"
The superuser and users of group "bluetooth" have these. You can check the policy here
/etc/dbus-1/system.d/bluetooth.conf
Best to check first if the user which later runs this script can execute bluetoothctl and get meaningful results
sudo -u www-data bluetoothctl show
- E.g. if you want to do bluetooth manipulation from the web interface, you will most likely need to add www-data to the group bluetooth
- if you want to test this script from the command line, you will most likely need to add user pi (or whoever you are) to the group bluetooth or run it as superuser
+ E.g. if you want to do bluetooth manipulation from the web interface, you will most likely need to add www-data
+ to the group bluetooth
+ if you want to test this script from the command line, you will most likely need to add user pi
+ (or whoever you are) to the group bluetooth or run it as superuser
sudo usermod -G bluetooth -a www-data
Don't forget to reboot for group changes to take effect here
@@ -86,14 +91,17 @@ def bt_switch(cmd, led_pin=None):
off = speakers, on = headphones
LED blinks if no bluetooth device is connected and bluetooth sink is requested, before script default to output 1
- A note for developers: This script is not persistent and only gets called (from various sources) when the output sink is changed/toggled and exits.
+ A note for developers: This script is not persistent and only gets called (from various sources)
+ when the output sink is changed/toggled and exits.
This is done to make is callable from button press (gpio button handler), rfid card number, web interface
- The LED state however should be persistent. With GPIOZero, the LED state gets reset at the end of the script. For that reason GPIO state is manipulated through shell commands
+ The LED state however should be persistent. With GPIOZero, the LED state gets reset at the end of the script.
+ For that reason GPIO state is manipulated through shell commands
Parameters
----------
:param cmd: string is "toggle" | "speakers" | "headphones"
- :param led_pin: integer with GPIO pin number of LED to reflect output status. If None, LED support is disabled (and no GPIO pin is blocked)
+ :param led_pin: integer with GPIO pin number of LED to reflect output status. If None, LED support is disabled
+ (and no GPIO pin is blocked)
"""
# Check for valid command
if cmd != "toggle" and cmd != "speakers" and cmd != "headphones":
@@ -127,14 +135,15 @@ def bt_switch(cmd, led_pin=None):
logger.debug(isSpeakerOn_console.stdout)
isSpeakerOn = re.search(b"^Output 1.*enabled", isSpeakerOn_console.stdout)
- # Figure out if a bluetooth device is connected (any device will do). Assume here that only speakers/headsets will be connected
+ # Figure out if a bluetooth device is connected (any device will do). Assume here that only speakers/headsets
+ # will be connected
# -> No need for user to adapt MAC address
# -> will actually support multiple speakers/headsets paired to the phoniebox
# Alternative: Check for specific bluetooth device only with "bluetoothctl info MACADDRESS"
isBtConnected_console = subprocess.run("bluetoothctl info", shell=True, check=False, stdout=subprocess.PIPE,
stderr=subprocess.STDOUT)
logger.debug(isBtConnected_console.stdout)
- isBtConnected = re.search(b"Connected:\s+yes", isBtConnected_console.stdout)
+ isBtConnected = re.search(b"Connected:\s+yes", isBtConnected_console.stdout) # noqa W605
if (cmd == "toggle" and isSpeakerOn) or (cmd == "headphones"):
# Only switch to BT headphones if they are actually connected
@@ -207,7 +216,7 @@ def get_led_pin_config(cfg_file):
if cfg[section_name].getboolean('enabled', fallback=False):
led_pin = cfg[section_name].getint('led_pin', fallback=None)
if not led_pin:
- logger.warning(f"Could not find 'led_pin' or could not read integer value")
+ logger.warning("Could not find 'led_pin' or could not read integer value")
elif not 1 <= led_pin <= 27:
logger.warning(f"Ignoring out of range pin number: {led_pin}.")
led_pin = None
diff --git a/components/controls/buttons-bluetooth-headphone/README.md b/components/controls/buttons-bluetooth-headphone/README.md
index 6cedd1207..a9256f690 100644
--- a/components/controls/buttons-bluetooth-headphone/README.md
+++ b/components/controls/buttons-bluetooth-headphone/README.md
@@ -1,15 +1,15 @@
-## Control Phoniebox via Buttons from Bluetooth Headset
+# Control Phoniebox via Buttons from Bluetooth Headset
Many bluetooth headsets or bluetooth speaker sets have buttons for controlling the music stream. **Let's make use of them!**
This component provides support for controlling your Phoniebox through these buttons on your bluetooth headset (or speaker set).
-### Installation
+## Installation
1. Make sure your bluetooth headset is connected to the Phoniebox. Follow the instructions in the [Wiki](https://github.com/MiczFlor/RPi-Jukebox-RFID/wiki/Connecting_Bluetooth_device_to_Phoniebox).
2. Execute `$ ./install-bt-buttons.sh. It will ask you to identify your headset and set up appropriate user rights, and registers the script as a service. It should work immediatly. In case of doubt, reboot.
- If later changing the headset, re-run `$ ./register-device.py`. Reboot or restart the service with `sudo systemctl restart phoniebox-bt-buttons.service`
-### Supported Buttons
+## Supported Buttons
Out-of-the box support is included for the following buttons
@@ -19,13 +19,15 @@ Out-of-the box support is included for the following buttons
Key codes are standarized and so it should also work with your headphones. If you want to add more keys or assign a different behaviour see [Troubleshooting](#troubleshooting)
-*Note:* Volume up/down is inherently supported by the bluetooth protocol. There is no need to handle these by this script.
+> [!NOTE]
+> Volume up/down is inherently supported by the bluetooth protocol. There is no need to handle these by this script.
-### On Connect / On Disconnect
+## On Connect / On Disconnect
If the feature [bluetooth-sink-switch](../../bluetooth-sink-switch) is enabled, the script automatically switches the audio stream to headphones / regular speakers on bluetooth connect / disconnect respectivly. Playback state (play/pause) is retained.
-*Note:* On-connect actions may take up to 4 seconds - please be patient (bluetooth connection is only checked every two seconds, bluetooth stream needs to be buffered, etc...)
+ > [!NOTE]
+ > On-connect actions may take up to 4 seconds - please be patient (bluetooth connection is only checked every two seconds, bluetooth stream needs to be buffered, etc...)
You can **customize** the behaviour by editing the functions
@@ -34,16 +36,16 @@ You can **customize** the behaviour by editing the functions
where `mpd_support` indicates wether the bt-sink-switch-feature is enabled.
-### Troubleshooting
+## Troubleshooting
This feature has been tested with PowerLocus Buddy and Sennheiser Momentum M2 AEBT headphones.
-#### Preparation
+### Preparation
- Stop the service `$ sudo systemctl stop phoniebox-bt-buttons.service`
- Start the script in a command line with debug option `$ ./bt-buttons.py debug`
-#### Check that correct bluetooth device is found
+### Check that correct bluetooth device is found
- Run the [preparatory steps](#preparation)
- Check headset is connected and listed as input event device with `$ cat /proc/bus/input/devices`. Note the device name.
@@ -57,7 +59,7 @@ This feature has been tested with PowerLocus Buddy and Sennheiser Momentum M2 AE
- If you see discrepancies, re-run `$ ./register-device.py`(see above)
-#### Add key codes / change actions
+### Add key codes / change actions
- Run the [preparatory steps](#preparation)
- Press the buttons on the headset and check for these debug outputs. Note down the keycode. The **163** is the keycode, you are looking for. Go through all the buttons. Also try short/long press. On my headphones, they result in different keycodes
@@ -78,7 +80,7 @@ This feature has been tested with PowerLocus Buddy and Sennheiser Momentum M2 AE
~~~
-#### Still having trouble?
+### Still having trouble?
Check the basics: test the event input. Make sure the headphones are connected beforehand. Replace event*X* with the event number obtained from `$ cat /proc/bus/input/devices`.
diff --git a/components/controls/buttons-bluetooth-headphone/bt-buttons.py b/components/controls/buttons-bluetooth-headphone/bt-buttons.py
index d079ae510..09dfaf25a 100755
--- a/components/controls/buttons-bluetooth-headphone/bt-buttons.py
+++ b/components/controls/buttons-bluetooth-headphone/bt-buttons.py
@@ -56,7 +56,7 @@ def bt_on_disconnect(mpd_support=0) -> None:
"""
logger.info("on disconnect")
if mpd_support:
- pctproc = subprocess.run(f"{os.path.dirname(os.path.realpath(__file__))}/../../../scripts/playout_controls.sh -c=bluetoothtoggle -v=speakers", shell=True, check=False,
+ pctproc = subprocess.run(f"{os.path.dirname(os.path.realpath(__file__))}/../../../scripts/playout_controls.sh -c=bluetoothtoggle -v=speakers", shell=True, check=False, # noqa: E501
stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
logger.debug(pctproc.stdout)
@@ -71,7 +71,7 @@ def bt_on_connect(mpd_support=0) -> None:
"""
logger.info("on connect")
if mpd_support:
- pctproc = subprocess.run(f"{os.path.dirname(os.path.realpath(__file__))}/../../../scripts/playout_controls.sh -c=bluetoothtoggle -v=headphones", shell=True, check=False,
+ pctproc = subprocess.run(f"{os.path.dirname(os.path.realpath(__file__))}/../../../scripts/playout_controls.sh -c=bluetoothtoggle -v=headphones", shell=True, check=False, # noqa: E501
stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
logger.debug(pctproc.stdout)
@@ -139,17 +139,17 @@ def bt_key_handler(name, mpd_support=0) -> None:
# Only act on button press, not button release
if event.value == 1:
if event.code == bt_keycode_play:
- proc = subprocess.run(f"{path}/../../../scripts/playout_controls.sh -c=playerpause", shell=True, check=False,
- stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
+ proc = subprocess.run(f"{path}/../../../scripts/playout_controls.sh -c=playerpause", shell=True,
+ check=False, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
elif event.code == bt_keycode_pause:
- proc = subprocess.run(f"{path}/../../../scripts/playout_controls.sh -c=playerpause", shell=True, check=False,
- stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
+ proc = subprocess.run(f"{path}/../../../scripts/playout_controls.sh -c=playerpause", shell=True,
+ check=False, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
elif event.code == bt_keycode_next:
- proc = subprocess.run(f"{path}/../../../scripts/playout_controls.sh -c=playernext", shell=True, check=False,
- stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
+ proc = subprocess.run(f"{path}/../../../scripts/playout_controls.sh -c=playernext", shell=True,
+ check=False, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
elif event.code == bt_keycode_prev:
- proc = subprocess.run(f"{path}/../../../scripts/playout_controls.sh -c=playerprev", shell=True, check=False,
- stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
+ proc = subprocess.run(f"{path}/../../../scripts/playout_controls.sh -c=playerprev", shell=True,
+ check=False, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
logger.debug(proc.stdout)
if proc.returncode != 0:
logger.error("#" * 60)
diff --git a/components/controls/buttons_usb_encoder/buttons_usb_encoder.py b/components/controls/buttons_usb_encoder/buttons_usb_encoder.py
index e8fa807a9..777278467 100644
--- a/components/controls/buttons_usb_encoder/buttons_usb_encoder.py
+++ b/components/controls/buttons_usb_encoder/buttons_usb_encoder.py
@@ -28,10 +28,11 @@
function_args = button_map[button_string + "_args"]
try:
getattr(function_calls, function_name)(function_args)
- except:
+ except Exception:
logger.warning(
- "Function " + function_name + " not found in function_calls.py (mapped from button: " + button_string + ")")
+ "Function " + function_name
+ + " not found in function_calls.py (mapped from button: " + button_string + ")")
except KeyError:
logger.warning("Button " + button_string + " not mapped to any function.")
-except:
+except Exception:
logger.error("An error with Buttons USB Encoder occurred.")
diff --git a/components/controls/buttons_usb_encoder/io_buttons_usb_encoder.py b/components/controls/buttons_usb_encoder/io_buttons_usb_encoder.py
index c20e5c366..2f03f8191 100644
--- a/components/controls/buttons_usb_encoder/io_buttons_usb_encoder.py
+++ b/components/controls/buttons_usb_encoder/io_buttons_usb_encoder.py
@@ -28,7 +28,7 @@ def current_device():
break
try:
_current_device
- except:
+ except Exception:
sys.exit('Could not find the device %s\n. Make sure it is connected' % device_name)
return _current_device
diff --git a/components/controls/buttons_usb_encoder/map_buttons_usb_encoder.py b/components/controls/buttons_usb_encoder/map_buttons_usb_encoder.py
index 394564de6..e832e1c52 100644
--- a/components/controls/buttons_usb_encoder/map_buttons_usb_encoder.py
+++ b/components/controls/buttons_usb_encoder/map_buttons_usb_encoder.py
@@ -11,7 +11,7 @@
sys.path.append(".")
-try:
+try: # noqa C901
functions = list(
filter(lambda function_name: function_name.startswith("functionCall"),
dir(components.gpio_control.function_calls.phoniebox_function_calls)))
@@ -43,7 +43,8 @@
button_map[button_string] = function_name
button_map[button_string + "_args"] = function_args
- print("Button '" + button_string + "' is now mapped to '" + function_name_short + "' with argument '" + str(function_args) + "'")
+ print("Button '" + button_string + "' is now mapped to '" + function_name_short
+ + "' with argument '" + str(function_args) + "'")
break
except KeyboardInterrupt:
continue
diff --git a/components/gpio_control/GPIODevices/simple_button.py b/components/gpio_control/GPIODevices/simple_button.py
index a022a812f..920358acf 100644
--- a/components/gpio_control/GPIODevices/simple_button.py
+++ b/components/gpio_control/GPIODevices/simple_button.py
@@ -106,11 +106,7 @@ def callbackFunctionHandler(self, *args):
if inval != GPIO.LOW:
return None
- if self.hold_mode in ('Repeat', 'Postpone', 'SecondFunc', 'SecondFuncRepeat'):
- return self.longPressHandler(*args)
- else:
- logger.info('{}: execute callback'.format(self.name))
- return self.when_pressed(*args)
+ return self._handleCallbackFunction(*args)
@property
def when_pressed(self):
@@ -136,36 +132,45 @@ def when_pressed(self, func):
def set_callbackFunction(self, callbackFunction):
self.when_pressed = callbackFunction
- def longPressHandler(self, *args):
- logger.info('{}: longPressHandler, mode: {}'.format(self.name, self.hold_mode))
- # instant action (except Postpone mode)
- if self.hold_mode != "Postpone":
- self.when_pressed(*args)
+ def _handleCallbackFunction(self, *args):
+ logger.info('{}: handleCallbackFunction, mode: {}'.format(self.name, self.hold_mode))
- # action(s) after hold_time
if self.hold_mode == "Repeat":
- # Repeated call of main action (multiple times if button is held long enough)
+ # Instantly call primary action
+ self.when_pressed(*args)
+ # Repeated call of primary action if button is held long enough
while checkGpioStaysInState(self.hold_time, self.pin, GPIO.LOW):
self.when_pressed(*args)
elif self.hold_mode == "Postpone":
- # Postponed call of main action (once)
+ # Postponed call of primary action (once)
if checkGpioStaysInState(self.hold_time, self.pin, GPIO.LOW):
self.when_pressed(*args)
- while checkGpioStaysInState(self.hold_time, self.pin, GPIO.LOW):
- pass
+ while checkGpioStaysInState(self.hold_time, self.pin, GPIO.LOW):
+ pass
elif self.hold_mode == "SecondFunc":
# Call of secondary action (once)
+ # execute primary action if not held past hold_time
if checkGpioStaysInState(self.hold_time, self.pin, GPIO.LOW):
self.when_held(*args)
- while checkGpioStaysInState(self.hold_time, self.pin, GPIO.LOW):
- pass
+ while checkGpioStaysInState(self.hold_time, self.pin, GPIO.LOW):
+ pass
+ else:
+ self.when_pressed(*args)
elif self.hold_mode == "SecondFuncRepeat":
# Repeated call of secondary action (multiple times if button is held long enough)
- while checkGpioStaysInState(self.hold_time, self.pin, GPIO.LOW):
+ # execute primary action if not held past hold_time
+ if checkGpioStaysInState(self.hold_time, self.pin, GPIO.LOW):
self.when_held(*args)
+ while checkGpioStaysInState(self.hold_time, self.pin, GPIO.LOW):
+ self.when_held(*args)
+ else:
+ self.when_pressed(*args)
+
+ else:
+ self.when_pressed(*args)
def __del__(self):
logger.debug('remove event detection')
diff --git a/components/gpio_control/README.md b/components/gpio_control/README.md
index bae060400..986526092 100644
--- a/components/gpio_control/README.md
+++ b/components/gpio_control/README.md
@@ -59,15 +59,19 @@ functionCall: functionCallPlayerPause
However, a button has more parameters than these. In the following comprehensive list you can also find the default values which are used automatically if you leave out these settings:
* **functionCallArgs**: Arguments for primary function, defaults to `None`. Arguments are ignored, if `functionCall` does not take any.
+
+> [!IMPORTANT]
+> Since v2.8.0 the behavior of `hold_mode` `SecondFunc` and `SecondFuncRepeat` has changed. The secondary function is no longer triggered additionally to the primary function.
+> Now its called exclusively if `hold_time` is reached. The primary function will only be triggered if the button is pressed shorter then `hold_time`!
+> Existing configurations may need to adapt to this.
+
* **hold_mode**: Specifies what shall happen if the button is held pressed for longer than `hold_time`:
* `None` (Default): Nothing special will happen.
- * `Repeat`: The configured `functionCall` is repeated after each `hold_time` interval.
+ * `Repeat`: The configured `functionCall` is instantly called and repeatedly after each `hold_time` interval.
* `Postpone`: The function will not be called before `hold_time`, i.e. the button needs to be pressed this long to activate the function
- * `SecondFunc`: Holding the button for at least `hold_time` will additionally execute the function `functionCall2` with `functionCall2Args`.
+ * `SecondFunc`: Pressing the button (shorter than `hold_time`) will execute the function `functionCall` with `functionCallArgs`. Holding the button for at least `hold_time` will execute the function `functionCall2` with `functionCall2Args`.
* `SecondFuncRepeat`: Like SecondFunc, but `functionCall2` is repeated after each `hold_time` interval.
- In every `hold_mode` except `Postpone`, the main action `functionCall` gets executed instantly.
-
Holding the button even longer than `hold_time` will cause no further action unless you are in the `Repeat` or `SecondFuncRepeat` mode.
* **hold_time**: Reference time for this buttons `hold_mode` feature in seconds. Default is `0.3`. This setting is ignored if `hold_mode` is unset or `None`
@@ -79,12 +83,13 @@ However, a button has more parameters than these. In the following comprehensive
* `pull_off`. Use this to deactivate internal pull-up/pulldown resistors. This is useful if your wiring includes your own (external) pull up / down resistors.
* **edge**: Configures the events in which the GPIO library shall trigger the callback function. Valid settings:
* `falling` (Default). Triggers if the GPIO voltage goes down.
- * `rising`. Trigegrs only if the GPIO voltage goes up.
+ * `rising`. Triggers only if the GPIO voltage goes up.
* `both`. Triggers in both cases.
* **bouncetime**: This is a setting of the GPIO library to limit bouncing effects during button usage. Default is `500` ms.
-* **antibouncehack**: Despite the integrated bounce reduction of the GPIO library some users may notice false triggers of their buttons (e.g. unrequested / double actions when releasing the button). If you encounter such problems, try setting this setting to `True` to activate an additional countermeasure.
+* **antibouncehack**: Despite the integrated bounce reduction of the GPIO library some users may notice false triggers of their buttons (e.g. unrequested / double actions when releasing the button). If you encounter such problems, try setting this to `True` to activate an additional countermeasure.
-Note: If you prefer, you may also use `Type: SimpleButton` instead of `Type: Button` - this makes no difference.
+> [!NOTE]
+> If you prefer, you may also use `Type: SimpleButton` instead of `Type: Button` - this makes no difference.
### ShutdownButton
@@ -113,7 +118,7 @@ Again, there are more parameters than these. In the following comprehensive list
* **iteration_time**: This parameter determines the flashing speed of the LED indicator. Default value is `0.2` seconds.
* **functionCall**: While the default action is `functionCallShutdown`, you might use this button type even with other functions than system shutdown (again, see [function documentation below](#functions) for a list of available functions).
-Furthermore, the following settings can be used as described for the [regular buttons](#doc_button): **pull_up_down**, **edge**, **bouncetime**, **antibouncehack**, **functionCallArgs**
+Furthermore, the following settings can be used as described for the [regular buttons](#button): **pull_up_down**, **edge**, **bouncetime**, **antibouncehack**, **functionCallArgs**
Note that using a ShutdownButton without a LED can also be implemented with a normal button like this:
@@ -186,14 +191,16 @@ functionCall2: functionCallVolD
* **functionCall1**: function called for every rotation step corresponding to rotary direction "clockwise". See below for passed arguments. See [function documentation below](#functions).
* **functionCall2**: function called for every rotation step corresponding to rotary direction "counter clockwise". See below for passed arguments. See [function documentation below](#functions).
* **timeBase**: Factor used for calculating the rotation value base on rotation speed, defaults to `0.1`. Use `0` for deactivating rotation speed influence.
-Example:
- * a single rotation step leads to the value 1 passed to the function.
- * steady rotation of two to or more steps, leads to the value 1 for the first call and the value 2 for all further calls.
- * speeding up rotation of two to or more steps, leads to the value 1 for the first call, the value 2 for the second, the value 3 for the third and so on.
-* **functionCall1Args**: Arguments for `functionCall1`, defaults to `None`. If defined takes precedence over rotation value. Arguments are ignored, if `functionCall1` does not take any.
-* **functionCall2Args**: Arguments for `functionCall2`, defaults to `None`. If defined takes precedence over rotation value. Arguments are ignored, if `functionCall1` does not take any.
+
+ Example:
+ * a single rotation step leads to the value 1 passed to the function.
+ * steady rotation of two to or more steps, leads to the value 1 for the first call and the value 2 for all further calls.
+ * speeding up rotation of two to or more steps, leads to the value 1 for the first call, the value 2 for the second, the value 3 for the third and so on.
+* **functionCall1Args**: Arguments for `functionCall1`, defaults to `None`. If defined takes precedence over rotation value. Arguments are ignored, if `functionCall1` does not take any.
+* **functionCall2Args**: Arguments for `functionCall2`, defaults to `None`. If defined takes precedence over rotation value. Arguments are ignored, if `functionCall1` does not take any.
To also use the push button of the encoder just a button definition:
+
```bash
[Mute]
enabled: True
@@ -204,7 +211,6 @@ functionCall: functionCallVol0
Note that the old configuration entries PinUp/PinDown and functionCallUp/functionCallDown are deprecated and might stop working in future.
-
```bash
[RotarySeekingControl]
enabled: True
@@ -220,9 +226,9 @@ functionCall2Args: 5
In this example, the encoder will be used to seek for- and backwards by 5 seconds on every rotation step. The rotation value will **NOT** be used in this case as the function args are defined!
-
#### Circuit diagram
-```text
+
+```text
.---------------. .---------------.
| | | |
| CLK |----------------------| GPIO 22 |
@@ -252,7 +258,9 @@ Pin: 14
* **Pin**: GPIO number of the LED (mandatory option). Note that you should not attach LEDs to GPIO ports without a matching resistor in line.
-Note: If you prefer, you may also use `Type: MPDStatusLED` instead of `Type: StatusLED` - this makes no difference.
+> [!NOTE]
+> If you prefer, you may also use `Type: MPDStatusLED` instead of
+> `Type: StatusLED` - this makes no difference.
### Further examples
@@ -306,6 +314,7 @@ In this example, a short press initiates a short jump forward by customized 5 se
For jumping backwards, this can be done equivalently (see [function list below](#functions)).
#### Use Buttons to start playlists
+
To use GPIO-Pins to play music, you can emulate a card scan with the function `functionCallTriggerPlayCardId`. Supply the `cardid` as `functionCallArgs`.
This behaves like a card scan, so you must link a folder to the id (on first press it will show up in the Web App as new card).
diff --git a/components/gpio_control/config_compatibility.py b/components/gpio_control/config_compatibility.py
index 9c2e92f5d..59a32f18d 100644
--- a/components/gpio_control/config_compatibility.py
+++ b/components/gpio_control/config_compatibility.py
@@ -1,10 +1,10 @@
#!/usr/bin/env python3
-import configparser
+
import os
from shutil import copyfile
-def Ini_CheckAndUpgrade(config):
+def Ini_CheckAndUpgrade(config): # noqa C901
has_changed = False
for section in config.sections():
# enable: True --> enabled: True
diff --git a/components/gpio_control/function_calls.py b/components/gpio_control/function_calls.py
index c3eda5913..9978a7695 100644
--- a/components/gpio_control/function_calls.py
+++ b/components/gpio_control/function_calls.py
@@ -100,10 +100,10 @@ def functionCallBluetoothToggle(self, mode=None, *args):
function_call("{command} -c=bluetoothtoggle -v={value}".format(command=self.playout_control, value=mode), shell=True)
def functionCallTriggerPlayCardId(self, cardid, *args):
- function_call("{command} --cardid={value}".format(command=self.rfid_trigger, value = cardid), shell=True)
+ function_call("{command} --cardid={value}".format(command=self.rfid_trigger, value=cardid), shell=True)
def functionCallTriggerPlayFolder(self, folder, *args):
- function_call("{command} --dir={value}".format(command=self.rfid_trigger, value = folder), shell=True)
+ function_call("{command} --dir={value}".format(command=self.rfid_trigger, value=folder), shell=True)
def getFunctionCall(self, functionName):
self.logger.error('Get FunctionCall: {} {}'.format(functionName, functionName in locals()))
diff --git a/components/gpio_control/test/test_SimpleButton.py b/components/gpio_control/test/test_SimpleButton.py
index d6f03acd3..b0b933e09 100644
--- a/components/gpio_control/test/test_SimpleButton.py
+++ b/components/gpio_control/test/test_SimpleButton.py
@@ -150,7 +150,7 @@ def test_hold_SecondFunc_longer_holdtime(self, simple_button):
simple_button.hold_mode = 'SecondFunc'
calls = mockedSecAction.call_count
simple_button.callbackFunctionHandler(simple_button.pin)
- mockedAction.assert_called_once()
+ mockedAction.assert_not_called()
assert mockedSecAction.call_count - calls == 1
def test_hold_SecondFunc_shorter_holdtime(self, simple_button):
@@ -170,7 +170,7 @@ def test_hold_SecondFuncRepeat_longer_holdtime(self, simple_button):
simple_button.hold_mode = 'SecondFuncRepeat'
calls = mockedSecAction.call_count
simple_button.callbackFunctionHandler(simple_button.pin)
- mockedAction.assert_called_once()
+ mockedAction.assert_not_called()
assert mockedSecAction.call_count - calls == 3
def test_hold_SecondFuncRepeat_shorter_holdtime(self, simple_button):
diff --git a/components/rfid-reader/RC522/README.md b/components/rfid-reader/RC522/README.md
index 156ce5a09..b84479a07 100644
--- a/components/rfid-reader/RC522/README.md
+++ b/components/rfid-reader/RC522/README.md
@@ -1,4 +1,6 @@
-# How to setup the RC522 RFID reader
+# RC522 Reader
+
+## How to setup the RC522 RFID reader
1. **You can use the `setup_rc522.sh` script (recommended)** or follow the manual steps:
@@ -15,3 +17,7 @@
- `sudo systemctl restart phoniebox-rfid-reader.service`
Be aware that unlike a few other installations with this card reader the phoniebox requires the IRQ pin to be connected (on the raspberry pi and zero normaly to GPIO 24 or PIN 18).
+
+## Working cards/tags
+
+Cards or tags must support 13.56 MHz. Currently, only cards/tags of the type "NXP Mifare Classic 1k(S50)", "NXP Mifare Classic 4k(S70)" and "NXP Mifare Ultralight (C)" can be used. Type "NXP Mifare NTAG2xx" will not work!
diff --git a/components/smart-home-automation/MQTT-protocol/daemon_mqtt_client.py b/components/smart-home-automation/MQTT-protocol/daemon_mqtt_client.py
index 583ad0c9b..87a5d070f 100644
--- a/components/smart-home-automation/MQTT-protocol/daemon_mqtt_client.py
+++ b/components/smart-home-automation/MQTT-protocol/daemon_mqtt_client.py
@@ -3,10 +3,9 @@
import datetime
import os
import re
-import ssl
import subprocess
import time
-from threading import *
+from threading import Thread
import inotify.adapters
import paho.mqtt.client as mqtt
diff --git a/components/synchronisation/sync-shared/README.md b/components/synchronisation/sync-shared/README.md
index 5bf9818aa..7417ca3fc 100644
--- a/components/synchronisation/sync-shared/README.md
+++ b/components/synchronisation/sync-shared/README.md
@@ -35,11 +35,11 @@ You may also change the settings in the according files directly.
### Settings
-**{INSTALLATION_ROOT}/settings/sync-shared-enabled**
+#### {INSTALLATION_ROOT}/settings/sync-shared-enabled
Holds the activation state of this feature. Values are "TRUE" or "FALSE"
-**{INSTALLATION_ROOT}/settings/sync-shared.conf**
+#### {INSTALLATION_ROOT}/settings/sync-shared.conf
SYNCSHAREDMODE: The mode to access the server files. SSH or MOUNT
diff --git a/htdocs/inc.setWlanIpMail.php b/htdocs/inc.setWlanIpMail.php
old mode 100755
new mode 100644
index d034aa2b3..4feb49bb0
--- a/htdocs/inc.setWlanIpMail.php
+++ b/htdocs/inc.setWlanIpMail.php
@@ -34,13 +34,18 @@
}
// Email address
$WlanIpMailAddr = trim($_POST['WlanIpMailAddr']);
- $exec = 'echo "'.$WlanIpMailAddr.'" > '.$conf['settings_abs'].'/WlanIpMailAddr';
- if($debug == "true") {
- print $exec;
+ if (filter_var($WlanIpMailAddr, FILTER_VALIDATE_EMAIL)) {
+ $WlanIpMailAddr = htmlspecialchars($WlanIpMailAddr, ENT_QUOTES, 'UTF-8');
+ $exec = 'echo "'.$WlanIpMailAddr.'" > '.$conf['settings_abs'].'/WlanIpMailAddr';
+ if($debug == "true") {
+ print $exec;
+ }
+ shell_exec($exec); // P36bd
+ } else {
+ echo "Invalid email address.";
}
- exec($exec);
// execute shell to create config file
- exec("sudo ".$conf['scripts_abs']."/inc.writeGlobalConfig.sh");
+ shell_exec("sudo ".$conf['scripts_abs']."/inc.writeGlobalConfig.sh"); // P36bd
}
?>
diff --git a/requirements-spotify.txt b/requirements-spotify.txt
index 2a27e9da5..380680b5b 100644
--- a/requirements-spotify.txt
+++ b/requirements-spotify.txt
@@ -3,4 +3,4 @@
Mopidy-Local
Mopidy-MPD
Mopidy-Iris==3.69.3
-Mopidy-Spotify==5.0.0a2
+Mopidy-Spotify==5.0.0a3
diff --git a/scripts/Reader.py b/scripts/Reader.py
index d3c09f2b6..b6ec9a4ba 100755
--- a/scripts/Reader.py
+++ b/scripts/Reader.py
@@ -45,7 +45,7 @@ def __init__(self):
break
try:
self.dev
- except:
+ except Exception:
sys.exit('Could not find the device %s\n. Make sure is connected' % deviceName)
def readCard(self):
diff --git a/scripts/Reader.py.Multi b/scripts/Reader.py.Multi
index 5e98b4d0f..1b2ac3d3d 100644
--- a/scripts/Reader.py.Multi
+++ b/scripts/Reader.py.Multi
@@ -49,7 +49,7 @@ class Reader:
for dev in devs:
try:
dev
- except:
+ except Exception:
sys.exit('Could not find the device %s\n. Make sure is connected' % dev.name)
str_devs = ','.join([str(x) for x in devs])
diff --git a/scripts/Reader.py.experimental b/scripts/Reader.py.experimental
index e3854f629..36429314c 100755
--- a/scripts/Reader.py.experimental
+++ b/scripts/Reader.py.experimental
@@ -11,7 +11,7 @@ import sys
import RPi.GPIO as GPIO
import logging
-from evdev import InputDevice, categorize, ecodes, list_devices
+from evdev import InputDevice, ecodes, list_devices
logger = logging.getLogger(__name__)
@@ -131,7 +131,7 @@ class Rdm6300Reader:
else:
return None
- def readCard(self):
+ def readCard(self): # noqa C901
byte_card_id = bytearray()
try:
@@ -188,7 +188,7 @@ class Pn532Reader:
from py532lib.i2c import Pn532_i2c
from py532lib.mifare import Mifare
from py532lib.mifare import MIFARE_WAIT_FOR_ENTRY
- pn532 = Pn532_i2c()
+ pn532 = Pn532_i2c() # noqa F841
self.device = Mifare()
self.device.SAMconfigure()
self.device.set_max_retries(MIFARE_WAIT_FOR_ENTRY)
@@ -213,7 +213,8 @@ class Reader(object):
if device_name == 'MFRC522':
self.reader = Mfrc522Reader()
elif device_name == 'RDM6300':
- # The Rdm6300Reader supports 2 Additional Number Formats which can bee choosen by an optional parameter dictionary:
+ # The Rdm6300Reader supports 2 Additional Number Formats which can be choosen
+ # by an optional parameter dictionary:
# {'numberformat':'card_id_float'} or {'numberformat':'card_id_dec'}
self.reader = Rdm6300Reader()
elif device_name == 'PN532':
diff --git a/scripts/Reader.py.experimental.Multi b/scripts/Reader.py.experimental.Multi
index b7c4fcb5f..a0d518ff7 100644
--- a/scripts/Reader.py.experimental.Multi
+++ b/scripts/Reader.py.experimental.Multi
@@ -17,13 +17,6 @@ import RPi.GPIO as GPIO
import logging
from enum import Enum
from evdev import InputDevice, ecodes, list_devices
-# Workaround: when using RC522 reader with pirc522 pkg the py532lib pkg may not be installed and vice-versa
-try:
- import pirc522
- from py532lib.i2c import *
- from py532lib.mifare import *
-except ImportError:
- pass
logger = logging.getLogger(__name__)
@@ -165,7 +158,10 @@ class Rdm6300Reader:
class Pn532Reader:
def __init__(self):
- pn532 = Pn532_i2c()
+ from py532lib.i2c import Pn532_i2c
+ from py532lib.mifare import Mifare
+ from py532lib.mifare import MIFARE_WAIT_FOR_ENTRY
+ pn532 = Pn532_i2c() # noqa F841
self.device = Mifare()
self.device.SAMconfigure()
self.device.set_max_retries(MIFARE_WAIT_FOR_ENTRY)
diff --git a/scripts/Reader.py.kkmoonRFIDreader b/scripts/Reader.py.kkmoonRFIDreader
index 10853b41b..0c55ec060 100755
--- a/scripts/Reader.py.kkmoonRFIDreader
+++ b/scripts/Reader.py.kkmoonRFIDreader
@@ -9,7 +9,7 @@ import os.path
import sys
-from evdev import InputDevice, categorize, ecodes, list_devices
+from evdev import InputDevice, ecodes, list_devices
from select import select
@@ -44,7 +44,7 @@ class Reader:
break
try:
self.dev
- except:
+ except Exception:
sys.exit('Could not find the device %s\n. Make sure is connected' % deviceName)
def readCard(self):
diff --git a/scripts/Reader.py.original b/scripts/Reader.py.original
index 80a4fabf3..1212155b3 100755
--- a/scripts/Reader.py.original
+++ b/scripts/Reader.py.original
@@ -19,7 +19,7 @@
import os.path
import sys
-from evdev import InputDevice, categorize, ecodes, list_devices
+from evdev import InputDevice, ecodes, list_devices
from select import select
import logging
logger = logging.getLogger(__name__)
@@ -51,7 +51,7 @@ class Reader:
break
try:
self.dev
- except:
+ except Exception:
sys.exit('Could not find the device %s\n. Make sure is connected' % deviceName)
def readCard(self):
diff --git a/scripts/Reader.py.pcsc b/scripts/Reader.py.pcsc
index 792b29f01..0cc50cd77 100644
--- a/scripts/Reader.py.pcsc
+++ b/scripts/Reader.py.pcsc
@@ -22,16 +22,12 @@ class Reader:
try:
hresult, hcontext = SCardEstablishContext(SCARD_SCOPE_USER)
if hresult != SCARD_S_SUCCESS:
- raise error(
- 'Failed to establish context: ' + \
- SCardGetErrorMessage(hresult))
+ raise error('Failed to establish context: ' + SCardGetErrorMessage(hresult))
try:
hresult, readers = SCardListReaders(hcontext, [])
if hresult != SCARD_S_SUCCESS:
- raise error(
- 'Failed to list readers: ' + \
- SCardGetErrorMessage(hresult))
+ raise error('Failed to list readers: ' + SCardGetErrorMessage(hresult))
readerstates = []
for i in range(len(readers)):
@@ -57,9 +53,7 @@ class Reader:
finally:
hresult = SCardReleaseContext(hcontext)
if hresult != SCARD_S_SUCCESS:
- raise error(
- 'Failed to release context: ' + \
- SCardGetErrorMessage(hresult))
+ raise error('Failed to release context: ' + SCardGetErrorMessage(hresult))
return (toHexString(response, PACK))
diff --git a/scripts/RegisterDevice.py.Multi b/scripts/RegisterDevice.py.Multi
index 008121496..9e9e40143 100644
--- a/scripts/RegisterDevice.py.Multi
+++ b/scripts/RegisterDevice.py.Multi
@@ -51,7 +51,7 @@ def setupMFRC522():
runCmd("cp {0}/scripts/Reader.py.experimental.Multi {1}/scripts/Reader.py".format(JUKEBOX_HOME_DIR, JUKEBOX_HOME_DIR))
-from Reader import get_devices, EDevices
+from Reader import get_devices, EDevices # noqa E402
list_dev_ids = list()
devices = get_devices()
diff --git a/scripts/daemon_rfid_reader.py b/scripts/daemon_rfid_reader.py
index b37c96bba..a7e5cf78f 100755
--- a/scripts/daemon_rfid_reader.py
+++ b/scripts/daemon_rfid_reader.py
@@ -57,7 +57,7 @@
# if controlcards delay is deactivated, let the cards pass, otherwise, they have to wait...
if sspc_nodelay == "ON":
- ids = re.findall("(\d+)", string)
+ ids = re.findall("(\d+)", string) # noqa W605
else:
ids = ""
@@ -69,7 +69,7 @@ def handler(signum, frame):
# force pause the player script
logger.info('Trigger Pause Force')
subprocess.call([dir_path + '/playout_controls.sh -c=playerpauseforce -v=0.1'], shell=True)
- except OSError as e:
+ except OSError:
logger.info('Execution of Pause failed.')
diff --git a/scripts/helperscripts/README.md b/scripts/helperscripts/README.md
index 7b22ab890..d5d0577cc 100644
--- a/scripts/helperscripts/README.md
+++ b/scripts/helperscripts/README.md
@@ -24,29 +24,29 @@ The created CSV file starts with the line
## CreatePodcastsKidsDeutsch.sh
-Creates sample folders with files and streams
+Creates sample folders with files and streams
inside the $AUDIOFOLDERSPATH directory
## CreateSampleAudiofoldersStreams.sh
-Creates sample folders with files and streams
+Creates sample folders with files and streams
inside the $AUDIOFOLDERSPATH directory
## DeleteAllConfig.sh
-This script will delete all config files
+This script will delete all config files
including mpd.conf and the like.
## DeleteSampleAudiofoldersStreams.sh
-Deletes sample folders with files and streams
+Deletes sample folders with files and streams
inside the $AUDIOFOLDERSPATH directory
## cli-player.py
Command line player to play folders on the Phoniebox.
-A command line replacement some functionality of the phoniebox-web-ui, which challenges the raspberry pi zero.
+A command line replacement some functionality of the phoniebox-web-ui, which challenges the raspberry pi zero.
Using this small script significantly reduces resource usage on the system.
## cli_ReadWifiIp.php
@@ -55,11 +55,11 @@ Reads out the IP of the Phoniebox in English language on boot.
## organizeFiles.py
-A small script for conveniently organizing audio folders,
-linking them to RFID cards, finding audio folders that are currently
+A small script for conveniently organizing audio folders,
+linking them to RFID cards, finding audio folders that are currently
not bound to any RFID card, and fixing broken links.
-A command line replacement some functionality of the phoniebox-web-ui, which challenges the raspberry pi zero.
+A command line replacement some functionality of the phoniebox-web-ui, which challenges the raspberry pi zero.
Using this small script significantly reduces resource usage on the system.
## setup_autohotspot.sh
@@ -67,17 +67,19 @@ Using this small script significantly reduces resource usage on the system.
Script to setup the autohotspot feature. It automatically sets up a wifi hotspot if no known network is found.
This is already included in the main install script, but can also be run manually. Please perform a reboot after you changed the configuration.
-usage:
+usage:
setup_autohotspot.sh \ \ \ \ \ \
### activate
-```
+
+```bash
chmod +x ./scripts/helperscripts/setup_autohotspot.sh
./scripts/helperscripts/setup_autohotspot.sh . YES phoniebox DE PlayItLoud 10.0.0.5
```
### deactivate
-```
+
+```bash
chmod +x ./scripts/helperscripts/setup_autohotspot.sh
./scripts/helperscripts/setup_autohotspot.sh . NO
```
diff --git a/scripts/helperscripts/organizeFiles.py b/scripts/helperscripts/organizeFiles.py
index 06c372633..7c387ec0f 100644
--- a/scripts/helperscripts/organizeFiles.py
+++ b/scripts/helperscripts/organizeFiles.py
@@ -2,7 +2,6 @@
# -*- coding: utf-8 -*-
-import sys
import os
import argparse
diff --git a/scripts/installscripts/install-jukebox.sh b/scripts/installscripts/install-jukebox.sh
index 9025afeba..28d0efbfc 100644
--- a/scripts/installscripts/install-jukebox.sh
+++ b/scripts/installscripts/install-jukebox.sh
@@ -963,8 +963,8 @@ install_main() {
# not yet available on apt.mopidy.com, so install manually
local arch=$(dpkg --print-architecture)
- local gst_plugin_spotify_name="gst-plugin-spotify_0.12.2-1_${arch}.deb"
- wget -q https://github.com/kingosticks/gst-plugins-rs-build/releases/download/gst-plugin-spotify_0.12.2-1/${gst_plugin_spotify_name}
+ local gst_plugin_spotify_name="gst-plugin-spotify_0.14.0.alpha.1-1_${arch}.deb"
+ wget -q https://github.com/kingosticks/gst-plugins-rs-build/releases/download/gst-plugin-spotify_0.14.0-alpha.1-1/${gst_plugin_spotify_name}
${apt_get} install ./${gst_plugin_spotify_name}
sudo rm -f ${gst_plugin_spotify_name}
diff --git a/settings/version-number b/settings/version-number
index 24ba9a38d..834f26295 100644
--- a/settings/version-number
+++ b/settings/version-number
@@ -1 +1 @@
-2.7.0
+2.8.0