Skip to content
Open
14 changes: 13 additions & 1 deletion config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,21 @@ config:
# For Linux/MacOS platforms, the CPU fan is amongst all fan sensors gathered from the motherboard chipset
# If value is AUTO the system monitor will try to auto-select the CPU fan
# If auto-detection fails, it might be necessary to manually indicate which fan is the CPU fan
# Value must be 'controller/fan' e.g. 'nct6798/fan2'. Use configuration wizard for help in selection
# Value must be 'controller/fan' e.g. 'it8628/fan1'. Use configuration wizard for help in selection
CPU_FAN: AUTO

# SYSTEM fan
# For Linux/MacOS platforms, the System fan is amongst all fan sensors gathered from the motherboard chipset
# If value is AUTO the system monitor will try to auto-select the System fan
# If auto-detection fails, it might be necessary to manually indicate which fan is the System fan
# Value must be 'controller/fan' e.g. 'nct6798/fan2'. Use configuration wizard for help in selection
SYS_FAN: it8628/fan5

# SYSTEM temperature sensor
# For Linux/MacOS platforms, the System temperature is amongst all temperature sensors gathered from the motherboard chipset
# Value must be 'controller/index' e.g. 'nct6798/0'. Use configuration wizard for help in selection
SYS_TEMP: it8628/0

# Address used for ping sensor. Can be internal/external IP (e.g. 8.8.8.8 or 192.168.0.1) or hostname (google.com)
PING: 8.8.8.8

Expand Down
12 changes: 12 additions & 0 deletions library/scheduler.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,12 @@ def CPUFanSpeed():
# logger.debug("Refresh CPU Fan Speed")
stats.CPU.fan_speed()

@async_job("CPU_FanPercent")
@schedule(timedelta(seconds=config.THEME_DATA['STATS']['CPU']['FAN_PERCENT'].get("INTERVAL", 0)).total_seconds())
def CPUFanPercent():
""" Refresh the CPU Fan Speed % """
# logger.debug("Refresh CPU Fan Speed %")
stats.CPU.fan_percent()

@async_job("GPU_Stats")
@schedule(timedelta(seconds=config.THEME_DATA['STATS'].get('GPU', {}).get("INTERVAL", 0)).total_seconds())
Expand All @@ -128,6 +134,12 @@ def GpuStats():
# logger.debug("Refresh GPU Stats")
stats.Gpu.stats()

@async_job("System_Stats")
@schedule(timedelta(seconds=config.THEME_DATA['STATS'].get("SYSTEM", {}).get("INTERVAL", 0)).total_seconds())
def SystemStats():
""" Refresh the System stats """
# logger.debug("Refresh System stats")
stats.System.stats()

@async_job("Memory_Stats")
@schedule(timedelta(seconds=config.THEME_DATA['STATS'].get('MEMORY', {}).get("INTERVAL", 0)).total_seconds())
Expand Down
19 changes: 19 additions & 0 deletions library/sensors/sensors.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,10 @@ def temperature() -> float:
def fan_percent(fan_name: str = None) -> float:
pass

@staticmethod
@abstractmethod
def fan_speed(fan_name: str = None) -> float:
pass

class Gpu(ABC):
@staticmethod
Expand Down Expand Up @@ -79,6 +83,21 @@ def frequency() -> float:
def is_available() -> bool:
pass

class System(ABC):
@staticmethod
@abstractmethod
def fan_percent(fan_name: str = None) -> float:
pass

@staticmethod
@abstractmethod
def fan_speed(fan_name: str = None) -> float:
pass

@staticmethod
@abstractmethod
def temperature(sys_name: str = None) -> float:
pass

class Memory(ABC):
@staticmethod
Expand Down
49 changes: 49 additions & 0 deletions library/sensors/sensors_librehardwaremonitor.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@
handle = Hardware.Computer()
handle.IsCpuEnabled = True
handle.IsGpuEnabled = True
handle.IsSystemEnabled = True
handle.IsMemoryEnabled = True
handle.IsMotherboardEnabled = True # For CPU Fan Speed
handle.IsControllerEnabled = True # For CPU Fan Speed
Expand Down Expand Up @@ -240,6 +241,22 @@ def temperature() -> float:

return math.nan

@staticmethod
def fan_speed(fan_name: str = None) -> float:
mb = get_hw_and_update(Hardware.HardwareType.Motherboard)
try:
for sh in mb.SubHardware:
sh.Update()
for sensor in sh.Sensors:
if sensor.SensorType == Hardware.SensorType.Control and "#2" in str(
sensor.Name) and sensor.Value is not None: # Is Motherboard #2 Fan always the CPU Fan ?
return float(sensor.Value)
except:
pass

# No Fan Speed sensor for this CPU model
return math.nan

@staticmethod
def fan_percent(fan_name: str = None) -> float:
mb = get_hw_and_update(Hardware.HardwareType.Motherboard)
Expand Down Expand Up @@ -377,6 +394,38 @@ def is_available(cls) -> bool:
cls.gpu_name = get_gpu_name()
return bool(cls.gpu_name)

class System(sensors.System):
@staticmethod
def fan_percent(fan_name: str = None) -> float:
mb = get_hw_and_update(Hardware.HardwareType.Motherboard)
try:
for sh in mb.SubHardware:
sh.Update()
for sensor in sh.Sensors:
if sensor.SensorType == Hardware.SensorType.Control and "#1" in str(
sensor.Name) and sensor.Value is not None: # Is Motherboard #1 Fan always the System Fan ?
return float(sensor.Value)
except:
pass

# No Fan Speed sensor for this CPU model
return math.nan

@staticmethod
def fan_speed(fan_name: str = None) -> float:
mb = get_hw_and_update(Hardware.HardwareType.Motherboard)
try:
for sh in mb.SubHardware:
sh.Update()
for sensor in sh.Sensors:
if sensor.SensorType == Hardware.SensorType.Control and "#1" in str(
sensor.Name) and sensor.Value is not None: # Is Motherboard #1 Fan always the System Fan ?
return float(sensor.Value)
except:
pass

# No Fan Speed sensor for this CPU model
return math.nan

class Memory(sensors.Memory):
@staticmethod
Expand Down
73 changes: 72 additions & 1 deletion library/sensors/sensors_python.py
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,24 @@ def temperature() -> float:
pass
return cpu_temp

@staticmethod
def fan_speed(fan_name: str = None) -> float:
try:
fans = sensors_fans()
if fans:
for name, entries in fans.items():
for entry in entries:
if fan_name is not None and fan_name == "%s/%s" % (name, entry.label):
# Manually selected fan
return entry.current
elif is_cpu_fan(entry.label) or is_cpu_fan(name):
# Auto-detected fan
return entry.current
except:
pass

return math.nan

@staticmethod
def fan_percent(fan_name: str = None) -> float:
try:
Expand All @@ -181,7 +199,6 @@ def fan_percent(fan_name: str = None) -> float:

return math.nan


class Gpu(sensors.Gpu):
@staticmethod
def stats() -> Tuple[
Expand Down Expand Up @@ -416,6 +433,60 @@ def is_available() -> bool:
except:
return False

class System(sensors.System):
@staticmethod
def fan_percent(fan_name: str = None) -> float:
try:
fans = sensors_fans()
if fans:
for name, entries in fans.items():
for entry in entries:
if fan_name is not None and fan_name == "%s/%s" % (name, entry.label):
# Manually selected fan
return entry.percent

elif is_cpu_fan(entry.label) or is_cpu_fan(name):
# Auto-detected fan
return entry.percent
except:
pass

return math.nan

@staticmethod
def fan_speed(fan_name: str = None) -> float:
try:
fans = sensors_fans()
if fans:
for name, entries in fans.items():
for entry in entries:
if fan_name is not None and fan_name == "%s/%s" % (name, entry.label):
# Manually selected fan
return entry.current

elif is_cpu_fan(entry.label) or is_cpu_fan(name):
# Auto-detected fan
return entry.current
except:
pass

return math.nan

@staticmethod
def temperature(sys_temp: str = None) -> float:
try:
sensors_temps = psutil.sensors_temperatures()
if sensors_temps:
arr_sys_temp = sys_temp.split("/")
if sensors_temps[arr_sys_temp[0]]:
if sensors_temps[arr_sys_temp[0]][int(arr_sys_temp[1])]:
return sensors_temps[arr_sys_temp[0]][int(arr_sys_temp[1])].current

except:
pass

return math.nan


class Memory(sensors.Memory):
@staticmethod
Expand Down
21 changes: 21 additions & 0 deletions library/sensors/sensors_stub_random.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@ def load() -> Tuple[float, float, float]: # 1 / 5 / 15min avg (%):
def temperature() -> float:
return random.uniform(30, 90)

@staticmethod
def fan_speed(fan_name: str = None) -> float:
return random.uniform(800, 2500)

@staticmethod
def fan_percent(fan_name: str = None) -> float:
return random.uniform(0, 100)
Expand Down Expand Up @@ -72,6 +76,23 @@ def frequency() -> float:
def is_available() -> bool:
return True

class System(sensors.System):
@staticmethod
def stats() -> Tuple[
float, float, float]: # fan (%) / fan speed / temp (°C)
return random.uniform(0, 100), random.uniform(800, 2500), random.uniform(30, 90)

@staticmethod
def fan_percent(fan_name: str = None) -> float:
return random.uniform(0, 100)

@staticmethod
def fan_speed(fan_name: str = None) -> float:
return random.uniform(800, 2500)

@staticmethod
def temperature(sys_temp: str = None) -> float:
return random.uniform(25, 50)

class Memory(sensors.Memory):
@staticmethod
Expand Down
24 changes: 24 additions & 0 deletions library/sensors/sensors_stub_static.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@

# Define other sensors
CPU_FREQ_MHZ = 2400.0
CPU_FAN_SPEED = 63.7
DISK_TOTAL_SIZE_GB = 1000
MEMORY_TOTAL_SIZE_GB = 64
GPU_MEM_TOTAL_SIZE_GB = 32
Expand All @@ -57,6 +58,10 @@ def load() -> Tuple[float, float, float]: # 1 / 5 / 15min avg (%):
def temperature() -> float:
return TEMPERATURE_SENSOR_VALUE

@staticmethod
def fan_speed(fan_name: str = None) -> float:
return CPU_FAN_SPEED

@staticmethod
def fan_percent(fan_name: str = None) -> float:
return PERCENTAGE_SENSOR_VALUE
Expand Down Expand Up @@ -88,6 +93,25 @@ def frequency() -> float:
def is_available() -> bool:
return True

class System(sensors.System):
@staticmethod
def stats() -> Tuple[
float, float, float]: # fan (%) / fan speed / temp (°C)
return (PERCENTAGE_SENSOR_VALUE,
CPU_FAN_SPEED,
TEMPERATURE_SENSOR_VALUE)

@staticmethod
def fan_percent(fan_name: str = None) -> float:
return PERCENTAGE_SENSOR_VALUE

@staticmethod
def fan_speed(fan_name: str = None) -> float:
return CPU_FAN_SPEED

@staticmethod
def temperature(sys_temp: str = None) -> float:
return TEMPERATURE_SENSOR_VALUE

class Memory(sensors.Memory):
@staticmethod
Expand Down
Loading