diff --git a/RGBHardwareMonitor/__main__.py b/RGBHardwareMonitor/__main__.py index 1131b87..7fd64f6 100644 --- a/RGBHardwareMonitor/__main__.py +++ b/RGBHardwareMonitor/__main__.py @@ -4,7 +4,9 @@ import configparser import traceback from time import sleep +from typing import Optional +from RGBHardwareMonitor.hardware_monitor import HMNoSensorsError from . import runtime from . import rgb_serial from . import hardware_monitor @@ -103,7 +105,23 @@ def real_main(): rgb_serial.arduino_id = runtime.config['RGBHardwareMonitor']['arduino_serial_id'] with RGBHardwareMonitorSysTray(animation_cls=WaitIconAnimation, start_animation=True) as systray: - rgb_serial.rings = ring_lights_from_cfg(runtime.config) # TODO: Handle sensor doesn't exist exception + init_exc: Optional[Exception] = None + for _ in range(3): + try: + rgb_serial.rings = ring_lights_from_cfg(runtime.config) + except HMNoSensorsError as exc: + init_exc = exc + sleeptime: float = 5.0 + logger.debug(f'Got no sensors found error. OpenHardwareMonitor initializing? Retrying in {sleeptime}') + sleep(sleeptime) + except Exception as exc: + init_exc = exc + raise + else: + init_exc = None + break + else: + raise RuntimeError(f'Initialization failed: {init_exc}') from init_exc while not quit_event.is_set(): if not pause_event.is_set(): rgb_serial.update_loop(systray=systray) diff --git a/RGBHardwareMonitor/hardware_monitor.py b/RGBHardwareMonitor/hardware_monitor.py index 590e27b..fdef24e 100644 --- a/RGBHardwareMonitor/hardware_monitor.py +++ b/RGBHardwareMonitor/hardware_monitor.py @@ -12,6 +12,30 @@ openhardwaremonitor_exe_path: Optional[str] = None +class HardwareMonitorError(Exception): + """Base class for hardware monitor exceptions""" + + +class HMExecError(HardwareMonitorError): + """Exception class for process execution errors""" + + +class HMWMIError(HardwareMonitorError): + """Exception class for WMI related errors""" + + +class HMWMINamespaceError(HMWMIError): + """Exception class for WMI namespace not found errors""" + + +class HMNoSensorsError(HardwareMonitorError): + """Exception class for no sensors returned from WMI query""" + + +class HMSensorNotFound(HardwareMonitorError): + """Exception class for sensor not found from WMI query""" + + # TODO: Catch WMI errors (like disconnection), check wmi lib @@ -26,7 +50,7 @@ def is_openhardwaremonitor_running(): def openhardwaremonitor_start(): if openhardwaremonitor_exe_path is None: - raise ValueError('Cannot run OpenHardwareMonitor: executable path not specified') + raise HMExecError('Cannot run OpenHardwareMonitor: executable path not specified') run_dir = Path(openhardwaremonitor_exe_path).parent logger.debug('Starting OpenHardwareMonitor...') run_as_admin(openhardwaremonitor_exe_path, run_dir=str(run_dir)) @@ -38,7 +62,7 @@ def openhardwaremonitor_start(): break retry -= 1 else: - raise RuntimeError('Failed starting OpenHardwareMonitor: WMI timed out') + raise HMWMIError('Failed starting OpenHardwareMonitor: WMI timed out') @dataclass @@ -213,7 +237,7 @@ def __post_init__(self, start_ohm): wmi_ohm = _wmi_get_ohm() if not is_openhardwaremonitor_running(): if not start_ohm: - raise RuntimeError('Failed while querying OpenHardwareMonitor WMI namespace. OHM not running?') + raise HMWMINamespaceError('Failed while querying OpenHardwareMonitor WMI namespace. OHM not running?') openhardwaremonitor_start() wmi_ohm = _wmi_get_ohm() self.name = WMI().Win32_ComputerSystem()[0].Name diff --git a/RGBHardwareMonitor/rgb_serial.py b/RGBHardwareMonitor/rgb_serial.py index 2bba7ca..e61d472 100644 --- a/RGBHardwareMonitor/rgb_serial.py +++ b/RGBHardwareMonitor/rgb_serial.py @@ -8,7 +8,7 @@ from .log import logger from .runtime import quit_event, pause_event -from .hardware_monitor import SystemInfo, Sensor +from .hardware_monitor import SystemInfo, Sensor, HMNoSensorsError, HMSensorNotFound from .systray import WaitIconAnimation, RunningIconAnimation @@ -32,7 +32,10 @@ class SensorSpec: def __post_init__(self): if self.__class__.system_info is None: self.__class__.system_info = SystemInfo(start_ohm=True) - for sensor in getattr(self.__class__.system_info, self.device).sensors: + sensors = getattr(self.__class__.system_info, self.device).sensors + if not sensors: + raise HMNoSensorsError('No sensors available from hardware monitor') + for sensor in sensors: for f_attr, f_val in self.filters.items(): if getattr(sensor, f_attr) != f_val: # if any filter fails, break loop break @@ -40,7 +43,7 @@ def __post_init__(self): self.sensor = sensor break else: - raise OSError(f'Sensor not found (device: {self.device}, filters: {str(self.filters)})') + raise HMSensorNotFound(f'Sensor not found (device: {self.device}, filters: {str(self.filters)})') @property def value(self):