diff --git a/python/common/src/piscsi/sys_cmds.py b/python/common/src/piscsi/sys_cmds.py index cb43360a..37c85f4a 100644 --- a/python/common/src/piscsi/sys_cmds.py +++ b/python/common/src/piscsi/sys_cmds.py @@ -3,13 +3,18 @@ Module with methods that interact with the Pi system """ import subprocess import logging +import sys from subprocess import run, CalledProcessError from shutil import disk_usage from re import findall, match from socket import socket, gethostname, AF_INET, SOCK_DGRAM from pathlib import Path from platform import uname -from vcgencmd import Vcgencmd + +try: + from vcgencmd import Vcgencmd +except ImportError: + pass from piscsi.return_codes import ReturnCodes from piscsi.common_settings import SHELL_ERROR @@ -276,26 +281,29 @@ class SysCmds: they're triggered. test_modes works similarly to enabled_mode but will ALWAYS display the modes listed for troubleshooting styling. """ - vcgcmd = Vcgencmd() - t_states = vcgcmd.get_throttled()['breakdown'] - matched_states = [] + if "vcgencmd" in sys.modules: + vcgcmd = Vcgencmd() + t_states = vcgcmd.get_throttled()["breakdown"] + matched_states = [] - state_msgs = { - "0": ("error", ReturnCodes.UNDER_VOLTAGE_DETECTED), - "1": ("warning", ReturnCodes.ARM_FREQUENCY_CAPPED), - "2": ("error", ReturnCodes.CURRENTLY_THROTTLED), - "3": ("warning", ReturnCodes.SOFT_TEMPERATURE_LIMIT_ACTIVE), - "16": ("warning", ReturnCodes.UNDER_VOLTAGE_HAS_OCCURRED), - "17": ("warning", ReturnCodes.ARM_FREQUENCY_CAPPING_HAS_OCCURRED), - "18": ("warning", ReturnCodes.THROTTLING_HAS_OCCURRED), - "19": ("warning", ReturnCodes.SOFT_TEMPERATURE_LIMIT_HAS_OCCURRED), - } + state_msgs = { + "0": ("error", ReturnCodes.UNDER_VOLTAGE_DETECTED), + "1": ("warning", ReturnCodes.ARM_FREQUENCY_CAPPED), + "2": ("error", ReturnCodes.CURRENTLY_THROTTLED), + "3": ("warning", ReturnCodes.SOFT_TEMPERATURE_LIMIT_ACTIVE), + "16": ("warning", ReturnCodes.UNDER_VOLTAGE_HAS_OCCURRED), + "17": ("warning", ReturnCodes.ARM_FREQUENCY_CAPPING_HAS_OCCURRED), + "18": ("warning", ReturnCodes.THROTTLING_HAS_OCCURRED), + "19": ("warning", ReturnCodes.SOFT_TEMPERATURE_LIMIT_HAS_OCCURRED), + } - for k in t_states: - if t_states[k] and k in enabled_modes: - matched_states.append(state_msgs[k]) + for k in t_states: + if t_states[k] and k in enabled_modes: + matched_states.append(state_msgs[k]) - for t in test_modes: - matched_states.append(state_msgs[t]) + for t in test_modes: + matched_states.append(state_msgs[t]) - return matched_states + return matched_states + else: + return [] diff --git a/python/web/requirements-dev.txt b/python/web/requirements-dev.txt index fd2bb2a1..f65d5f8c 100644 --- a/python/web/requirements-dev.txt +++ b/python/web/requirements-dev.txt @@ -4,3 +4,4 @@ black==22.8.0 flake8==5.0.4 watchdog==2.1.9 requests==2.31.0 +vcgencmd==0.1.1 diff --git a/python/web/src/return_code_mapper.py b/python/web/src/return_code_mapper.py index 9695a1dd..95025d9b 100644 --- a/python/web/src/return_code_mapper.py +++ b/python/web/src/return_code_mapper.py @@ -51,21 +51,28 @@ class ReturnCodeMapper: ReturnCodes.EXTRACTIMAGE_COMMAND_ERROR: _("Unable to extract archive: %(error)s"), ReturnCodes.UNDER_VOLTAGE_DETECTED: - _("Under voltage detected - Make sure to use a proper power source (2.5+ amps)."), + _("Potential instability - Under voltage detected - Make sure to use a sufficient " + "power source (2.5+ amps)."), ReturnCodes.ARM_FREQUENCY_CAPPED: - _("ARM frequency capped - Ensure proper airflow/cooling."), + _("Potential instability - ARM frequency capped - Ensure sufficient airflow/cooling."), ReturnCodes.CURRENTLY_THROTTLED: - _("Currently throttled - Make sure to use a proper power source (2.5+ amps)."), + _("Potential instability - Currently throttled - Make sure to use a sufficient power " + "source (2.5+ amps)."), ReturnCodes.SOFT_TEMPERATURE_LIMIT_ACTIVE: - _("Soft-temperature limit active - Ensure proper airflow/cooling."), + _("Potential instability - Soft-temperature limit active - Ensure sufficient " + "airflow/cooling."), ReturnCodes.UNDER_VOLTAGE_HAS_OCCURRED: - _("Under voltage has occurred since last reboot. Make sure to use a proper power source (2.5+ amps)."), + _("Potential instability - Under voltage has occurred since last reboot. Make sure " + "to use a sufficient power source (2.5+ amps)."), ReturnCodes.ARM_FREQUENCY_CAPPING_HAS_OCCURRED: - _("ARM frequency capping has occurred since last reboot. Ensure proper airflow/cooling."), + _("Potential instability - ARM frequency capping has occurred since last reboot. " + "Ensure sufficient airflow/cooling."), ReturnCodes.THROTTLING_HAS_OCCURRED: - _("Throttling has occurred since the last reboot. Make sure to use a proper power source (2.5+ amps)."), + _("Potential instability - Throttling has occurred since the last reboot. Make sure " + "to use a sufficient power source (2.5+ amps)."), ReturnCodes.SOFT_TEMPERATURE_LIMIT_HAS_OCCURRED: - _("Soft temperature limit has occurred since last reboot. Ensure proper airflow/cooling."), + _("Potential instability - Soft temperature limit has occurred since last reboot. " + "Ensure sufficient airflow/cooling."), } # fmt: on diff --git a/python/web/src/settings.py b/python/web/src/settings.py index 7bcc99c3..5994c719 100644 --- a/python/web/src/settings.py +++ b/python/web/src/settings.py @@ -33,7 +33,7 @@ TEMPLATE_THEME_DEFAULT = "modern" TEMPLATE_THEME_LEGACY = "classic" # Enable throttle notifications -# +# # Available modes: # "0": "Under-voltage detected" # "1": "Arm frequency capped" diff --git a/python/web/src/static/themes/classic/style.css b/python/web/src/static/themes/classic/style.css index c5da7eed..3c8b754a 100644 --- a/python/web/src/static/themes/classic/style.css +++ b/python/web/src/static/themes/classic/style.css @@ -173,7 +173,7 @@ summary.filename { margin-left: -27px; } -div.throttle_notice > div { +div.throttle-notice > div { display: grid; align-items: center; background-color: #efefef; @@ -185,23 +185,21 @@ div.throttle_notice > div { justify-content: center; } -div.throttle_notice > div.error { +div.throttle-notice > div.error { background-color: #dc3545; align-items: center; } -div.throttle_notice > div.warning { +div.throttle-notice > div.warning { background-color: #ffc107; align-items: center; } -div.throttle_notice > div a { +div.throttle-notice > div a { color: black; text-decoration: none; } -div.throttle_notice > div a:hover { +div.throttle-notice > div a:hover { text-decoration: underline; } - - diff --git a/python/web/src/static/themes/modern/style.css b/python/web/src/static/themes/modern/style.css index f6c55871..a21a91ed 100644 --- a/python/web/src/static/themes/modern/style.css +++ b/python/web/src/static/themes/modern/style.css @@ -476,7 +476,7 @@ div.footer div.theme-change-hint a { ------------------------------------------------------------------------------ */ -div.throttle_notice > div { +div.throttle-notice > div { display: grid; align-items: center; background-color: #efefef; @@ -487,29 +487,29 @@ div.throttle_notice > div { font-weight: bold; } -div.throttle_notice > div.error { +div.throttle-notice > div.error { background-color: var(--danger); background-image: url("icons/error.svg"); color: #fff; align-items: center; } -div.throttle_notice > div.warning { +div.throttle-notice > div.warning { background-color: var(--warning); background-image: url("icons/warning.svg"); align-items: center; } -div.throttle_notice > div > span.message { - padding-left: 3rem; +div.throttle-notice > div > span.message { + padding-left: 3rem; } -div.throttle_notice > div a { +div.throttle-notice > div a { color: black; text-decoration: none; } -div.throttle_notice > div a:hover { +div.throttle-notice > div a:hover { text-decoration: underline; } diff --git a/python/web/src/templates/base.html b/python/web/src/templates/base.html index 5bca87b2..1bcb16e4 100644 --- a/python/web/src/templates/base.html +++ b/python/web/src/templates/base.html @@ -73,13 +73,12 @@ -
+
{% if (env["throttle_status"]|length > 0) %} {% for category, response in env["throttle_status"] %}
Potential - instability due to: {{ response['msg'] }} + href="https://www.raspberrypi.com/documentation/computers/configuration.html#undervoltage-warning">{{ response['msg'] }}
{% endfor %} {% endif %} diff --git a/python/web/src/web.py b/python/web/src/web.py index 732ef0fe..a550a95c 100644 --- a/python/web/src/web.py +++ b/python/web/src/web.py @@ -90,8 +90,7 @@ def get_env_info(): else: username = None - throttled_statuses = sys_cmd.get_throttled( - THROTTLE_NOTIFY_MODES, THROTTLE_TEST_MODES) + throttled_statuses = sys_cmd.get_throttled(THROTTLE_NOTIFY_MODES, THROTTLE_TEST_MODES) return { "running_env": sys_cmd.running_env(), @@ -111,8 +110,9 @@ def get_env_info(): "cd_suffixes": tuple(server_info["sccd"]), "rm_suffixes": tuple(server_info["scrm"]), "mo_suffixes": tuple(server_info["scmo"]), - "throttle_status": - [(s[0], ReturnCodeMapper.add_msg({"return_code":s[1]})) for s in throttled_statuses], + "throttle_status": [ + (s[0], ReturnCodeMapper.add_msg({"return_code": s[1]})) for s in throttled_statuses + ], } diff --git a/python/web/tests/api/test_settings.py b/python/web/tests/api/test_settings.py index 1c51205a..3875fd9e 100644 --- a/python/web/tests/api/test_settings.py +++ b/python/web/tests/api/test_settings.py @@ -286,12 +286,3 @@ def test_rename_system(env, http_client): response_data = response.json() assert response_data["data"]["system_name"] == old_name - - -def test_throttle_notification(http_client): - response = http_client.get("/") - response_data = response.json() - - assert response.status_code == 200 - assert response_data["status"] == STATUS_SUCCESS - assert "Under voltage detected" in response_data["data"]