Improved support for AMD CPU sensors
* K8, K10, and K11? should be treated the same as CoreTemp * These are included in osTicket posts * Cleaned up code for pylint * Removed unused join_columns() function
This commit is contained in:
parent
9c80c357d6
commit
4912b17bf3
2 changed files with 45 additions and 44 deletions
|
|
@ -1557,7 +1557,7 @@ def run_mprime_test(state, test):
|
||||||
# Add temps to report
|
# Add temps to report
|
||||||
test.report.append('{BLUE}Temps{CLEAR}'.format(**COLORS))
|
test.report.append('{BLUE}Temps{CLEAR}'.format(**COLORS))
|
||||||
for line in generate_sensor_report(
|
for line in generate_sensor_report(
|
||||||
test.sensor_data, 'Idle', 'Max', 'Cooldown', core_only=True):
|
test.sensor_data, 'Idle', 'Max', 'Cooldown', cpu_only=True):
|
||||||
test.report.append(' {}'.format(line))
|
test.report.append(' {}'.format(line))
|
||||||
|
|
||||||
# Add abort message(s)
|
# Add abort message(s)
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,6 @@
|
||||||
# Wizard Kit: Functions - Sensors
|
'''Wizard Kit: Functions - Sensors'''
|
||||||
|
# pylint: disable=no-name-in-module,wildcard-import
|
||||||
|
# vim: sts=2 sw=2 ts=2
|
||||||
|
|
||||||
import json
|
import json
|
||||||
import re
|
import re
|
||||||
|
|
@ -9,7 +11,7 @@ from settings.sensors import *
|
||||||
|
|
||||||
# Error Classes
|
# Error Classes
|
||||||
class ThermalLimitReachedError(Exception):
|
class ThermalLimitReachedError(Exception):
|
||||||
pass
|
'''Thermal limit reached error.'''
|
||||||
|
|
||||||
|
|
||||||
def clear_temps(sensor_data):
|
def clear_temps(sensor_data):
|
||||||
|
|
@ -20,28 +22,30 @@ def clear_temps(sensor_data):
|
||||||
_data['Temps'] = []
|
_data['Temps'] = []
|
||||||
|
|
||||||
|
|
||||||
def fix_sensor_str(s):
|
def fix_sensor_str(_s):
|
||||||
"""Cleanup string and return str."""
|
"""Cleanup string and return str."""
|
||||||
s = re.sub(r'^(\w+)-(\w+)-(\w+)', r'\1 (\2 \3)', s, re.IGNORECASE)
|
_s = re.sub(r'^(\w+)-(\w+)-(\w+)', r'\1 (\2 \3)', _s, re.IGNORECASE)
|
||||||
s = s.title()
|
_s = _s.title()
|
||||||
s = s.replace('Coretemp', 'CoreTemp')
|
_s = _s.replace('Coretemp', 'CPUTemp')
|
||||||
s = s.replace('Acpi', 'ACPI')
|
_s = _s.replace('Acpi', 'ACPI')
|
||||||
s = s.replace('ACPItz', 'ACPI TZ')
|
_s = _s.replace('ACPItz', 'ACPI TZ')
|
||||||
s = s.replace('Isa ', 'ISA ')
|
_s = _s.replace('Isa ', 'ISA ')
|
||||||
s = s.replace('Id ', 'ID ')
|
_s = _s.replace('Pci ', 'PCI ')
|
||||||
s = re.sub(r'(\D+)(\d+)', r'\1 \2', s, re.IGNORECASE)
|
_s = _s.replace('Id ', 'ID ')
|
||||||
s = s.replace(' ', ' ')
|
_s = re.sub(r'(\D+)(\d+)', r'\1 \2', _s, re.IGNORECASE)
|
||||||
return s
|
_s = re.sub(r'^K (\d+)Temp', r'AMD K\1 Temps', _s, re.IGNORECASE)
|
||||||
|
_s = re.sub(r'T(ctl|die)', r'CPU (T\1)', _s, re.IGNORECASE)
|
||||||
|
return _s
|
||||||
|
|
||||||
|
|
||||||
def generate_sensor_report(
|
def generate_sensor_report(
|
||||||
sensor_data, *temp_labels,
|
sensor_data, *temp_labels,
|
||||||
colors=True, core_only=False):
|
colors=True, cpu_only=False):
|
||||||
"""Generate report based on temp_labels, returns list if str."""
|
"""Generate report based on temp_labels, returns list if str."""
|
||||||
report = []
|
report = []
|
||||||
for _section, _adapters in sorted(sensor_data.items()):
|
for _section, _adapters in sorted(sensor_data.items()):
|
||||||
# CoreTemps then Other temps
|
# CPU temps then Other temps
|
||||||
if core_only and 'Core' not in _section:
|
if cpu_only and 'CPU' not in _section:
|
||||||
continue
|
continue
|
||||||
for _adapter, _sources in sorted(_adapters.items()):
|
for _adapter, _sources in sorted(_adapters.items()):
|
||||||
# Adapter
|
# Adapter
|
||||||
|
|
@ -56,7 +60,7 @@ def generate_sensor_report(
|
||||||
': ' if _label != 'Current' else '',
|
': ' if _label != 'Current' else '',
|
||||||
get_temp_str(_data.get(_label, '???'), colors=colors))
|
get_temp_str(_data.get(_label, '???'), colors=colors))
|
||||||
report.append(_line)
|
report.append(_line)
|
||||||
if not core_only:
|
if not cpu_only:
|
||||||
report.append(' ')
|
report.append(' ')
|
||||||
|
|
||||||
# Handle empty reports (i.e. no sensors detected)
|
# Handle empty reports (i.e. no sensors detected)
|
||||||
|
|
@ -91,15 +95,15 @@ def get_colored_temp_str(temp):
|
||||||
else:
|
else:
|
||||||
color = COLORS['CLEAR']
|
color = COLORS['CLEAR']
|
||||||
return '{color}{prefix}{temp:2.0f}°C{CLEAR}'.format(
|
return '{color}{prefix}{temp:2.0f}°C{CLEAR}'.format(
|
||||||
color = color,
|
color=color,
|
||||||
prefix = '-' if temp < 0 else '',
|
prefix='-' if temp < 0 else '',
|
||||||
temp = temp,
|
temp=temp,
|
||||||
**COLORS)
|
**COLORS)
|
||||||
|
|
||||||
|
|
||||||
def get_raw_sensor_data():
|
def get_raw_sensor_data():
|
||||||
"""Read sensor data and return dict."""
|
"""Read sensor data and return dict."""
|
||||||
data = {}
|
json_data = {}
|
||||||
cmd = ['sensors', '-j']
|
cmd = ['sensors', '-j']
|
||||||
|
|
||||||
# Get raw data
|
# Get raw data
|
||||||
|
|
@ -122,8 +126,8 @@ def get_raw_sensor_data():
|
||||||
try:
|
try:
|
||||||
json_data = json.loads('\n'.join(raw_data))
|
json_data = json.loads('\n'.join(raw_data))
|
||||||
except json.JSONDecodeError:
|
except json.JSONDecodeError:
|
||||||
# Still broken, just set to empty dict
|
# Still broken, just return the empty dict
|
||||||
json_data = {}
|
pass
|
||||||
|
|
||||||
# Done
|
# Done
|
||||||
return json_data
|
return json_data
|
||||||
|
|
@ -132,10 +136,10 @@ def get_raw_sensor_data():
|
||||||
def get_sensor_data():
|
def get_sensor_data():
|
||||||
"""Parse raw sensor data and return new dict."""
|
"""Parse raw sensor data and return new dict."""
|
||||||
json_data = get_raw_sensor_data()
|
json_data = get_raw_sensor_data()
|
||||||
sensor_data = {'CoreTemps': {}, 'Other': {}}
|
sensor_data = {'CPUTemps': {}, 'Other': {}}
|
||||||
for _adapter, _sources in json_data.items():
|
for _adapter, _sources in json_data.items():
|
||||||
if 'coretemp' in _adapter:
|
if is_cpu_adapter(_adapter):
|
||||||
_section = 'CoreTemps'
|
_section = 'CPUTemps'
|
||||||
else:
|
else:
|
||||||
_section = 'Other'
|
_section = 'Other'
|
||||||
sensor_data[_section][_adapter] = {}
|
sensor_data[_section][_adapter] = {}
|
||||||
|
|
@ -157,8 +161,8 @@ def get_sensor_data():
|
||||||
}
|
}
|
||||||
|
|
||||||
# Remove empty sections
|
# Remove empty sections
|
||||||
for k, v in sensor_data.items():
|
for _k, _v in sensor_data.items():
|
||||||
v = {k2: v2 for k2, v2 in v.items() if v2}
|
_v = {_k2: _v2 for _k2, _v2 in _v.items() if _v2}
|
||||||
|
|
||||||
# Done
|
# Done
|
||||||
return sensor_data
|
return sensor_data
|
||||||
|
|
@ -178,14 +182,20 @@ def get_temp_str(temp, colors=True):
|
||||||
temp)
|
temp)
|
||||||
|
|
||||||
|
|
||||||
|
def is_cpu_adapter(adapter):
|
||||||
|
"""Checks if adapter is a known CPU adapter, returns bool."""
|
||||||
|
is_cpu = re.search(r'(core|k\d+)temp', adapter, re.IGNORECASE)
|
||||||
|
return bool(is_cpu)
|
||||||
|
|
||||||
|
|
||||||
def monitor_sensors(monitor_pane, monitor_file):
|
def monitor_sensors(monitor_pane, monitor_file):
|
||||||
"""Continually update sensor data and report to screen."""
|
"""Continually update sensor data and report to screen."""
|
||||||
sensor_data = get_sensor_data()
|
sensor_data = get_sensor_data()
|
||||||
while True:
|
while True:
|
||||||
update_sensor_data(sensor_data)
|
update_sensor_data(sensor_data)
|
||||||
with open(monitor_file, 'w') as f:
|
with open(monitor_file, 'w') as _f:
|
||||||
report = generate_sensor_report(sensor_data, 'Current', 'Max')
|
report = generate_sensor_report(sensor_data, 'Current', 'Max')
|
||||||
f.write('\n'.join(report))
|
_f.write('\n'.join(report))
|
||||||
sleep(1)
|
sleep(1)
|
||||||
if monitor_pane and not tmux_poll_pane(monitor_pane):
|
if monitor_pane and not tmux_poll_pane(monitor_pane):
|
||||||
break
|
break
|
||||||
|
|
@ -196,7 +206,7 @@ def save_average_temp(sensor_data, temp_label, seconds=10):
|
||||||
clear_temps(sensor_data)
|
clear_temps(sensor_data)
|
||||||
|
|
||||||
# Get temps
|
# Get temps
|
||||||
for i in range(seconds):
|
for _i in range(seconds): # pylint: disable=unused-variable
|
||||||
update_sensor_data(sensor_data)
|
update_sensor_data(sensor_data)
|
||||||
sleep(1)
|
sleep(1)
|
||||||
|
|
||||||
|
|
@ -219,24 +229,15 @@ def update_sensor_data(sensor_data, thermal_limit=None):
|
||||||
_data['Current'] = _temp
|
_data['Current'] = _temp
|
||||||
_data['Max'] = max(_temp, _data['Max'])
|
_data['Max'] = max(_temp, _data['Max'])
|
||||||
_data['Temps'].append(_temp)
|
_data['Temps'].append(_temp)
|
||||||
except Exception:
|
except Exception: # pylint: disable=broad-except
|
||||||
# Dumb workound for Dell sensors with changing source names
|
# Dumb workound for Dell sensors with changing source names
|
||||||
pass
|
pass
|
||||||
|
|
||||||
# Check if thermal limit reached
|
# Check if thermal limit reached
|
||||||
if thermal_limit and _section == 'CoreTemps':
|
if thermal_limit and _section == 'CPUTemps':
|
||||||
if max(_data['Current'], _data['Max']) >= thermal_limit:
|
if max(_data['Current'], _data['Max']) >= thermal_limit:
|
||||||
raise ThermalLimitReachedError('CoreTemps reached limit')
|
raise ThermalLimitReachedError('CPU temps reached limit')
|
||||||
|
|
||||||
|
|
||||||
def join_columns(column1, column2, width=55):
|
|
||||||
return '{:<{}}{}'.format(
|
|
||||||
column1,
|
|
||||||
55+len(column1)-len(REGEX_COLORS.sub('', column1)),
|
|
||||||
column2)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
print("This file is not meant to be called directly.")
|
print("This file is not meant to be called directly.")
|
||||||
|
|
||||||
# vim: sts=2 sw=2 ts=2
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue