Skip to content

System sensors #834

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@ -118,6 +118,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 @@ -126,6 +132,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 @@ -49,6 +49,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 @@ -77,6 +81,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 @@ -64,6 +64,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 @@ -238,6 +239,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 @@ -375,6 +392,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 @@ -152,6 +152,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 @@ -170,7 +188,6 @@ def fan_percent(fan_name: str = None) -> float:

return math.nan


class Gpu(sensors.Gpu):
@staticmethod
def stats() -> Tuple[
Expand Down Expand Up @@ -405,6 +422,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 @@ -42,6 +42,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 @@ -70,6 +74,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 @@ -30,6 +30,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 @@ -55,6 +56,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 @@ -86,6 +91,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