From 33e9cde0f447894c711bba0a579b007901ac877b Mon Sep 17 00:00:00 2001 From: 2Shirt <2xShirt@gmail.com> Date: Sun, 17 Sep 2023 18:11:09 -0700 Subject: [PATCH] Keep history of sensor temps Needed for #204 --- scripts/wk/hw/diags.py | 34 ++++++++++++++++++++-------------- scripts/wk/hw/sensors.py | 22 +++++++++++++++++++--- 2 files changed, 39 insertions(+), 17 deletions(-) diff --git a/scripts/wk/hw/diags.py b/scripts/wk/hw/diags.py index b08bf5eb..19974363 100644 --- a/scripts/wk/hw/diags.py +++ b/scripts/wk/hw/diags.py @@ -317,7 +317,7 @@ def build_menu(cli_mode=False, quick_mode=False) -> cli.Menu: return menu -def cpu_tests_init(state) -> None: +def cpu_tests_init(state: State) -> None: """Initialize CPU tests.""" sensors_out = pathlib.Path(f'{state.log_dir}/sensors.out') state.update_title_text(state.system.cpu_description) @@ -338,19 +338,20 @@ def cpu_tests_init(state) -> None: # Save idle temps cli.print_standard('Saving idle temps...') - state.sensors.save_average_temps(temp_label='Idle', seconds=5) + state.sensors.save_average_temps(temp_label='Idle', seconds=5, save_history=False) -def cpu_tests_end(state) -> None: +def cpu_tests_end(state: State) -> None: """End CPU tests.""" # Cleanup + state.sensors.clear_temps(next_label='Done') state.sensors.stop_background_monitor() state.ui.clear_current_pane_height() state.ui.remove_all_info_panes() state.ui.remove_all_worker_panes() -def cpu_test_cooling(state, test_object, test_mode=False) -> None: +def cpu_test_cooling(state: State, test_object, test_mode=False) -> None: """CPU cooling test via sensor data assessment.""" _ = test_mode LOG.info('CPU Test (Cooling)') @@ -363,7 +364,7 @@ def cpu_test_cooling(state, test_object, test_mode=False) -> None: state.update_progress_file() -def cpu_test_mprime(state, test_object, test_mode=False) -> None: +def cpu_test_mprime(state: State, test_object, test_mode=False) -> None: """CPU stress test using mprime.""" LOG.info('CPU Test (Prime95)') aborted = False @@ -389,6 +390,7 @@ def cpu_test_mprime(state, test_object, test_mode=False) -> None: print('') # Start sensors monitor + state.sensors.clear_temps(next_label='Prime95') state.sensors.stop_background_monitor() state.sensors.start_background_monitor( sensors_out, @@ -412,6 +414,7 @@ def cpu_test_mprime(state, test_object, test_mode=False) -> None: if 'Cooldown' in state.sensors.temp_labels: # Give Prime95 time to save the results std.sleep(1) + state.sensors.clear_temps(next_label='Cooldown') else: # Save cooldown temp state.ui.clear_current_pane() @@ -436,7 +439,7 @@ def cpu_test_mprime(state, test_object, test_mode=False) -> None: raise std.GenericAbort('Aborted') -def cpu_test_sysbench(state, test_object, test_mode=False) -> None: +def cpu_test_sysbench(state: State, test_object, test_mode=False) -> None: """CPU stress test using Sysbench.""" LOG.info('CPU Test (Sysbench)') aborted = False @@ -458,6 +461,7 @@ def cpu_test_sysbench(state, test_object, test_mode=False) -> None: print('') # Start sensors monitor + state.sensors.clear_temps(next_label='Sysbench') state.sensors.stop_background_monitor() state.sensors.start_background_monitor( sensors_out, @@ -478,7 +482,9 @@ def cpu_test_sysbench(state, test_object, test_mode=False) -> None: hw_cpu.stop_sysbench(proc, filehandle) # Get cooldown temp - if 'Cooldown' not in state.sensors.temp_labels: + if 'Cooldown' in state.sensors.temp_labels: + state.sensors.clear_temps(next_label='Cooldown') + else: state.ui.clear_current_pane() cli.print_standard('Letting CPU cooldown...') std.sleep(5) @@ -515,7 +521,7 @@ def cpu_test_sysbench(state, test_object, test_mode=False) -> None: raise std.GenericAbort('Aborted') -def disk_attribute_check(state, test_objects, test_mode=False) -> None: +def disk_attribute_check(state: State, test_objects, test_mode=False) -> None: """Disk attribute check.""" _ = test_mode LOG.info('Disk Attribute Check') @@ -593,7 +599,7 @@ def disk_io_benchmark( raise std.GenericAbort('Aborted') -def disk_self_test(state, test_objects, test_mode=False) -> None: +def disk_self_test(state: State, test_objects, test_mode=False) -> None: """Disk self-test if available.""" _ = test_mode LOG.info('Disk Self-Test(s)') @@ -686,7 +692,7 @@ def disk_smart_status_check(dev, mid_run=True) -> None: dev.disable_disk_tests() -def disk_surface_scan(state, test_objects, test_mode=False) -> None: +def disk_surface_scan(state: State, test_objects, test_mode=False) -> None: """Read-only disk surface scan using badblocks.""" LOG.info('Disk Surface Scan (badblocks)') aborted = False @@ -838,7 +844,7 @@ def print_countdown(proc, seconds) -> None: # Done print('') -def run_cpu_tests(state, test_objects, test_mode=False) -> None: +def run_cpu_tests(state: State, test_objects, test_mode=False) -> None: """Run selected CPU test(s).""" state.update_progress_file() cpu_tests_init(state) @@ -849,7 +855,7 @@ def run_cpu_tests(state, test_objects, test_mode=False) -> None: state.update_progress_file() -def run_diags(state, menu, quick_mode=False, test_mode=False) -> None: +def run_diags(state: State, menu, quick_mode=False, test_mode=False) -> None: """Run selected diagnostics.""" aborted = False atexit.register(state.save_debug_reports) @@ -902,7 +908,7 @@ def run_diags(state, menu, quick_mode=False, test_mode=False) -> None: cli.pause('Press Enter to return to main menu...') -def show_failed_attributes(state) -> None: +def show_failed_attributes(state: State) -> None: """Show failed attributes for all disks.""" for dev in state.disks: cli.print_colored([dev.name, dev.description], ['CYAN', None]) @@ -912,7 +918,7 @@ def show_failed_attributes(state) -> None: cli.print_standard('') -def show_results(state) -> None: +def show_results(state: State) -> None: """Show test results by device.""" std.sleep(0.5) state.ui.clear_current_pane() diff --git a/scripts/wk/hw/sensors.py b/scripts/wk/hw/sensors.py index ce3c9f24..eb0098f3 100644 --- a/scripts/wk/hw/sensors.py +++ b/scripts/wk/hw/sensors.py @@ -6,6 +6,7 @@ import logging import pathlib import re +from copy import deepcopy from subprocess import CalledProcessError from threading import Thread from typing import Any @@ -40,11 +41,21 @@ class Sensors(): def __init__(self): self.background_thread: Thread | None = None self.data: dict[Any, Any] = get_sensor_data() + self.history: list[tuple[str, dict]] = [] self.out_path: pathlib.Path | str | None = None + self.history_next_label: str = 'Idle' self.temp_labels: set = set(['Current', 'Max']) - def clear_temps(self) -> None: + def clear_temps(self, next_label: str, save_history: bool = True) -> None: """Clear saved temps but keep structure""" + prev_label = self.history_next_label + self.history_next_label = next_label + + # Save history + if save_history: + self.history.append((prev_label, deepcopy(self.data))) + + # Clear data for adapters in self.data.values(): for sources in adapters.values(): for source_data in sources.values(): @@ -158,9 +169,14 @@ class Sensors(): # Sleep before next loop sleep(0.5) - def save_average_temps(self, temp_label, seconds=10) -> None: + def save_average_temps( + self, + temp_label: str, + seconds: int = 10, + save_history: bool = True, + ) -> None: """Save average temps under temp_label over provided seconds..""" - self.clear_temps() + self.clear_temps(next_label=temp_label, save_history=save_history) self.temp_labels.add(temp_label) # Get temps