diff --git a/external/LibreHardwareMonitor/test_librehardwaremonitor.py b/external/LibreHardwareMonitor/test_librehardwaremonitor.py index 3788b9d9..7c08b65f 100644 --- a/external/LibreHardwareMonitor/test_librehardwaremonitor.py +++ b/external/LibreHardwareMonitor/test_librehardwaremonitor.py @@ -43,6 +43,7 @@ handle.IsControllerEnabled = True handle.IsNetworkEnabled = True handle.IsStorageEnabled = True +handle.IsPsuEnabled = True handle.Open() for hw in handle.Hardware: diff --git a/library/lcd/lcd_comm.py b/library/lcd/lcd_comm.py index 86e9dcad..0cef5d02 100644 --- a/library/lcd/lcd_comm.py +++ b/library/lcd/lcd_comm.py @@ -76,7 +76,7 @@ def openSerial(self): if self.com_port == 'AUTO': lcd_com_port = self.auto_detect_com_port() if not lcd_com_port: - logger.error("Cannot find COM port automatically, please set it manually in config.yaml") + logger.error("Cannot find COM port automatically, please run Configuration again and select COM port manually") try: sys.exit(0) except: diff --git a/library/sensors/sensors_librehardwaremonitor.py b/library/sensors/sensors_librehardwaremonitor.py index fe1cf305..5429ed8e 100644 --- a/library/sensors/sensors_librehardwaremonitor.py +++ b/library/sensors/sensors_librehardwaremonitor.py @@ -87,14 +87,79 @@ logger.info("Found Network interface: %s" % hardware.Name) -def get_hw_and_update(hwtype: Hardware.HardwareType) -> Hardware.Hardware: +def get_hw_and_update(hwtype: Hardware.HardwareType, name: str = None) -> Hardware.Hardware: for hardware in handle.Hardware: if hardware.HardwareType == hwtype: - hardware.Update() - return hardware + if (name and hardware.Name == name) or not name: + hardware.Update() + return hardware return None +def get_gpu_name() -> str: + # Determine which GPU to use, in case there are multiple : try to avoid using discrete GPU for stats + hw_gpus = [] + for hardware in handle.Hardware: + if hardware.HardwareType == Hardware.HardwareType.GpuNvidia \ + or hardware.HardwareType == Hardware.HardwareType.GpuAmd \ + or hardware.HardwareType == Hardware.HardwareType.GpuIntel: + hw_gpus.append(hardware) + + if len(hw_gpus) == 0: + # No supported GPU found on the system + logger.warning("No supported GPU found") + return "" + elif len(hw_gpus) == 1: + # Found one supported GPU + logger.debug("Found one supported GPU: %s" % hw_gpus[0].Name) + return str(hw_gpus[0].Name) + else: + # Found multiple GPUs, try to determine which one to use + amd_gpus = 0 + intel_gpus = 0 + nvidia_gpus = 0 + + gpu_to_use = "" + + # Count GPUs by manufacturer + for gpu in hw_gpus: + if gpu.HardwareType == Hardware.HardwareType.GpuAmd: + amd_gpus += 1 + elif gpu.HardwareType == Hardware.HardwareType.GpuIntel: + intel_gpus += 1 + elif gpu.HardwareType == Hardware.HardwareType.GpuNvidia: + nvidia_gpus += 1 + + logger.warning( + "Found %d GPUs on your system (%d AMD / %d Nvidia / %d Intel). Auto identify which GPU to use." % ( + len(hw_gpus), amd_gpus, nvidia_gpus, intel_gpus)) + + if nvidia_gpus >= 1: + # One (or more) Nvidia GPU: use first available for stats + gpu_to_use = get_hw_and_update(Hardware.HardwareType.GpuNvidia).Name + elif amd_gpus == 1: + # No Nvidia GPU, only one AMD GPU: use it + gpu_to_use = get_hw_and_update(Hardware.HardwareType.GpuAmd).Name + elif amd_gpus > 1: + # No Nvidia GPU, several AMD GPUs found: try to use the real GPU but not the APU integrated in CPU + for gpu in hw_gpus: + if gpu.HardwareType == Hardware.HardwareType.GpuAmd: + for sensor in gpu.Sensors: + if sensor.SensorType == Hardware.SensorType.Load and str(sensor.Name).startswith("GPU Core"): + # Found load sensor for this GPU: assume it is main GPU and use it for stats + gpu_to_use = gpu.Name + else: + # No AMD or Nvidia GPU: there are several Intel GPUs, use first available for stats + gpu_to_use = get_hw_and_update(Hardware.HardwareType.GpuIntel).Name + + if gpu_to_use: + logger.debug("This GPU will be used for stats: %s" % gpu_to_use) + else: + logger.warning("No supported GPU found (no GPU with load sensor)") + + return gpu_to_use + + def get_net_interface_and_update(if_name: str) -> Hardware.Hardware: for hardware in handle.Hardware: if hardware.HardwareType == Hardware.HardwareType.Network and hardware.Name == if_name: @@ -173,13 +238,16 @@ def temperature() -> float: class Gpu(sensors.Gpu): - @staticmethod - def stats() -> Tuple[float, float, float, float]: # load (%) / used mem (%) / used mem (Mb) / temp (°C) - gpu_to_use = get_hw_and_update(Hardware.HardwareType.GpuAmd) + # GPU to use is detected once, and its name is saved for future sensors readings + gpu_name = "" + + @classmethod + def stats(cls) -> Tuple[float, float, float, float]: # load (%) / used mem (%) / used mem (Mb) / temp (°C) + gpu_to_use = get_hw_and_update(Hardware.HardwareType.GpuAmd, cls.gpu_name) if gpu_to_use is None: - gpu_to_use = get_hw_and_update(Hardware.HardwareType.GpuNvidia) + gpu_to_use = get_hw_and_update(Hardware.HardwareType.GpuNvidia, cls.gpu_name) if gpu_to_use is None: - gpu_to_use = get_hw_and_update(Hardware.HardwareType.GpuIntel) + gpu_to_use = get_hw_and_update(Hardware.HardwareType.GpuIntel, cls.gpu_name) if gpu_to_use is None: # GPU not supported return math.nan, math.nan, math.nan, math.nan @@ -206,17 +274,10 @@ def stats() -> Tuple[float, float, float, float]: # load (%) / used mem (%) / u return load, (used_mem / total_mem * 100.0), used_mem, temp - @staticmethod - def is_available() -> bool: - found_amd = (get_hw_and_update(Hardware.HardwareType.GpuAmd) is not None) - found_nvidia = (get_hw_and_update(Hardware.HardwareType.GpuNvidia) is not None) - found_intel = (get_hw_and_update(Hardware.HardwareType.GpuIntel) is not None) - - if (found_amd and (found_nvidia or found_intel)) or (found_nvidia and found_intel): - logger.info( - "Found multiple GPUs on your system. Will use dedicated GPU (AMD/Nvidia) for stats if possible.") - - return found_amd or found_nvidia or found_intel + @classmethod + def is_available(cls) -> bool: + cls.gpu_name = get_gpu_name() + return bool(cls.gpu_name) class Memory(sensors.Memory):