mirror of
https://github.com/akuker/RASCSI.git
synced 2024-12-21 08:29:59 +00:00
Add web UI notification for under voltage/throttling events (#1203)
This commit is contained in:
parent
3b6822d7c8
commit
b32027f8c0
@ -6,7 +6,7 @@ Please check out the full story with much more detail on the [wiki](https://gith
|
||||
# How do I contribute?
|
||||
PiSCSI is using the <a href="https://datasift.github.io/gitflow/IntroducingGitFlow.html">Gitflow Workflow</a>. A quick overview:
|
||||
|
||||
- The *master* branch should always reflect the contents of the last stable release
|
||||
- The *main* branch should always reflect the contents of the last stable release
|
||||
- The *develop* branch should contain the latest tested & approved updates. Pull requests should be used to merge changes into develop.
|
||||
- The rest of the feature branches are for developing new features
|
||||
- A tag will be created for each "release". The releases will be named <year>.<month>.<release number> where the release number is incremented for each subsequent release tagged in the same calendar month. The first release of the month of January 2021 is called "21.01.01", the second one in the same month "21.01.02" and so on.
|
||||
|
@ -1,2 +1,3 @@
|
||||
protobuf==3.19.5
|
||||
requests==2.31.0
|
||||
vcgencmd==0.1.1
|
||||
|
@ -27,3 +27,11 @@ class ReturnCodes:
|
||||
EXTRACTIMAGE_NO_FILES_SPECIFIED = 91
|
||||
EXTRACTIMAGE_NO_FILES_EXTRACTED = 92
|
||||
EXTRACTIMAGE_COMMAND_ERROR = 93
|
||||
UNDER_VOLTAGE_DETECTED = 100
|
||||
ARM_FREQUENCY_CAPPED = 101
|
||||
CURRENTLY_THROTTLED = 102
|
||||
SOFT_TEMPERATURE_LIMIT_ACTIVE = 103
|
||||
UNDER_VOLTAGE_HAS_OCCURRED = 116
|
||||
ARM_FREQUENCY_CAPPING_HAS_OCCURRED = 117
|
||||
THROTTLING_HAS_OCCURRED = 118
|
||||
SOFT_TEMPERATURE_LIMIT_HAS_OCCURRED = 119
|
||||
|
@ -9,7 +9,9 @@ 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
|
||||
|
||||
from piscsi.return_codes import ReturnCodes
|
||||
from piscsi.common_settings import SHELL_ERROR
|
||||
|
||||
|
||||
@ -263,3 +265,37 @@ class SysCmds:
|
||||
return process.returncode, process.stdout.decode("utf-8")
|
||||
|
||||
return process.returncode, process.stderr.decode("utf-8")
|
||||
|
||||
@staticmethod
|
||||
def get_throttled(enabled_modes, test_modes):
|
||||
"""
|
||||
Takes (list) enabled_modes & (list) test_modes parameters & returns a
|
||||
tuple of (str) category & (str) message.
|
||||
|
||||
enabled_modes is a list of modes that will be enabled for display if
|
||||
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 = []
|
||||
|
||||
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 t in test_modes:
|
||||
matched_states.append(state_msgs[t])
|
||||
|
||||
return matched_states
|
||||
|
23
python/web/mock/bin/vcgencmd
Normal file
23
python/web/mock/bin/vcgencmd
Normal file
@ -0,0 +1,23 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Info: https://www.raspberrypi.com/documentation/computers/os.html#vcgencmd
|
||||
#
|
||||
# Bit Hex value Meaning
|
||||
# ----- ----------- ------------------------
|
||||
# 0 0x1 Under-voltage detected
|
||||
# 1 0x2 Arm frequency capped
|
||||
# 2 0x4 Currently throttled
|
||||
# 3 0x8 Soft temperature limit active
|
||||
# 16 0x10000 Under-voltage has occurred
|
||||
# 17 0x20000 Arm frequency capping has occurred
|
||||
# 18 0x40000 Throttling has occurred
|
||||
# 19 0x80000 Soft temperature limit has occurred
|
||||
|
||||
if [[ "$1" == "get_throttled" ]]
|
||||
then
|
||||
# Return 'Under-voltage detected' & 'Under-voltage has occurred'
|
||||
echo "throttled=0x10001"
|
||||
fi
|
||||
|
||||
echo "Mock does not recognize: $0 $@"
|
||||
exit 1
|
@ -6,3 +6,4 @@ requests==2.31.0
|
||||
simplepam==0.1.5
|
||||
flask_babel==2.0.0
|
||||
ua-parser==0.16.1
|
||||
vcgencmd==0.1.1
|
@ -50,6 +50,22 @@ class ReturnCodeMapper:
|
||||
_("No files were extracted (existing files are skipped)"),
|
||||
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)."),
|
||||
ReturnCodes.ARM_FREQUENCY_CAPPED:
|
||||
_("ARM frequency capped - Ensure proper airflow/cooling."),
|
||||
ReturnCodes.CURRENTLY_THROTTLED:
|
||||
_("Currently throttled - Make sure to use a proper power source (2.5+ amps)."),
|
||||
ReturnCodes.SOFT_TEMPERATURE_LIMIT_ACTIVE:
|
||||
_("Soft-temperature limit active - Ensure proper 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)."),
|
||||
ReturnCodes.ARM_FREQUENCY_CAPPING_HAS_OCCURRED:
|
||||
_("ARM frequency capping has occurred since last reboot. Ensure proper airflow/cooling."),
|
||||
ReturnCodes.THROTTLING_HAS_OCCURRED:
|
||||
_("Throttling has occurred since the last reboot. Make sure to use a proper power source (2.5+ amps)."),
|
||||
ReturnCodes.SOFT_TEMPERATURE_LIMIT_HAS_OCCURRED:
|
||||
_("Soft temperature limit has occurred since last reboot. Ensure proper airflow/cooling."),
|
||||
}
|
||||
# fmt: on
|
||||
|
||||
|
@ -31,3 +31,19 @@ TEMPLATE_THEME_DEFAULT = "modern"
|
||||
|
||||
# Fallback theme for older browsers
|
||||
TEMPLATE_THEME_LEGACY = "classic"
|
||||
|
||||
# Enable throttle notifications
|
||||
#
|
||||
# Available modes:
|
||||
# "0": "Under-voltage detected"
|
||||
# "1": "Arm frequency capped"
|
||||
# "2": "Currently throttled"
|
||||
# "3": "Soft temperature limit active"
|
||||
# "16": "Under-voltage has occurred"
|
||||
# "17": "Arm frequency capping has occurred"
|
||||
# "18": "Throttling has occurred"
|
||||
# "19": "Soft temperature limit has occurred"
|
||||
THROTTLE_NOTIFY_MODES = ["0", "16"]
|
||||
# Include a list of modes to be shown ALL THE TIME to be used for styling
|
||||
# and formatting.
|
||||
THROTTLE_TEST_MODES = []
|
||||
|
@ -172,3 +172,36 @@ summary.filename {
|
||||
left: 50%;
|
||||
margin-left: -27px;
|
||||
}
|
||||
|
||||
div.throttle_notice > div {
|
||||
display: grid;
|
||||
align-items: center;
|
||||
background-color: #efefef;
|
||||
background-repeat: no-repeat;
|
||||
background-position: 1rem center;
|
||||
background-size: 1rem;
|
||||
font-size: x-small;
|
||||
font-weight: bold;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
div.throttle_notice > div.error {
|
||||
background-color: #dc3545;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
div.throttle_notice > div.warning {
|
||||
background-color: #ffc107;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
div.throttle_notice > div a {
|
||||
color: black;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
div.throttle_notice > div a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
|
||||
|
@ -470,6 +470,49 @@ div.footer div.theme-change-hint a {
|
||||
color: yellow;
|
||||
}
|
||||
|
||||
/*
|
||||
------------------------------------------------------------------------------
|
||||
Throttle messages
|
||||
------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
div.throttle_notice > div {
|
||||
display: grid;
|
||||
align-items: center;
|
||||
background-color: #efefef;
|
||||
background-repeat: no-repeat;
|
||||
background-position: 1rem center;
|
||||
background-size: 1rem;
|
||||
font-size: x-small;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
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 {
|
||||
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 a {
|
||||
color: black;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
div.throttle_notice > div a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
/*
|
||||
------------------------------------------------------------------------------
|
||||
Flash messages
|
||||
|
@ -73,6 +73,18 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="throttle_notice">
|
||||
{% if (env["throttle_status"]|length > 0) %}
|
||||
{% for category, response in env["throttle_status"] %}
|
||||
<div class="{{ category }}">
|
||||
<span class="message" title="{{ response['msg'] }}"><a
|
||||
href="https://www.raspberrypi.com/documentation/computers/configuration.html#undervoltage-warning">Potential
|
||||
instability due to: {{ response['msg'] }}</a></span>
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<div class="flash" id="flash">
|
||||
{% if get_flashed_messages(): %}
|
||||
{% for category, message in get_flashed_messages(with_categories=true) %}
|
||||
|
@ -69,6 +69,8 @@ from settings import (
|
||||
TEMPLATE_THEMES,
|
||||
TEMPLATE_THEME_DEFAULT,
|
||||
TEMPLATE_THEME_LEGACY,
|
||||
THROTTLE_NOTIFY_MODES,
|
||||
THROTTLE_TEST_MODES,
|
||||
)
|
||||
|
||||
|
||||
@ -88,6 +90,9 @@ def get_env_info():
|
||||
else:
|
||||
username = None
|
||||
|
||||
throttled_statuses = sys_cmd.get_throttled(
|
||||
THROTTLE_NOTIFY_MODES, THROTTLE_TEST_MODES)
|
||||
|
||||
return {
|
||||
"running_env": sys_cmd.running_env(),
|
||||
"username": username,
|
||||
@ -106,6 +111,8 @@ 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],
|
||||
}
|
||||
|
||||
|
||||
|
@ -286,3 +286,12 @@ 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"]
|
||||
|
Loading…
Reference in New Issue
Block a user