UshakovVasilii / gnome-shell-extension-freon

Shows CPU temperature, disk temperature, video card temperature (NVIDIA/Catalyst/Bumblebee&NVIDIA), voltage and fan RPM
https://extensions.gnome.org/extension/841/freon
GNU General Public License v2.0
427 stars 77 forks source link

sensorsUtil: read drivetemp sensors as disk temperature sensors #217

Closed illwieckz closed 2 years ago

illwieckz commented 2 years ago

When drivetemp kernel module is loaded, the sensors utility can display drive temperatures.

It's an alternative way to udisks and hddtemp.

I noticed udisks is very laggy in a way the displayed temperature may be very old, and I also noticed temperature discrepancies between udisks and hddtemp, and I trust hddtemp more.

I noticed hddtemp may not report temperature when a drive is sleeping.

I noticed querying a drive in some other way I don't remember may also wake-up the drive from sleeping, which is not wanted.

I've discovered it exists a drivetemp module that allows sensors to display the drive temperature as user. The drawback is that it displays some identifier like drivetemp-scsi-5-0 and not the drive names.

For some reasons this module is not loaded by default even not suggested by sensors-detect, but it works well.

This PR makes possible to fetch drivetemp temperatures from sensors as drive temperatures (otherwise they are listed as generic temperatures).

illwieckz commented 2 years ago

It would be possible to fetch the drive name as user with some tricks.

For example, this command:

sensors --no-adapter 'drivetemp-*'

would output:

drivetemp-scsi-9-0
temp1:        +40.0°C  (low  =  +0.0°C, high = +100.0°C)
                       (crit low =  +0.0°C, crit = +100.0°C)
                       (lowest = +36.0°C, highest = +60.0°C)

drivetemp-scsi-6-0
temp1:        +44.0°C  (low  = +10.0°C, high = +40.0°C)
                       (crit low =  +5.0°C, crit = +60.0°C)
                       (lowest = +37.0°C, highest = +46.0°C)

drivetemp-scsi-4-0
temp1:        +40.0°C  (low  = +10.0°C, high = +40.0°C)
                       (crit low =  +5.0°C, crit = +60.0°C)
                       (lowest = +34.0°C, highest = +41.0°C)

drivetemp-scsi-13-0
temp1:        +38.0°C  (low  =  +0.0°C, high = +100.0°C)
                       (crit low =  +0.0°C, crit = +100.0°C)
                       (lowest = +35.0°C, highest = +51.0°C)

drivetemp-scsi-7-0
temp1:        +41.0°C  (low  = +10.0°C, high = +40.0°C)
                       (crit low =  +5.0°C, crit = +60.0°C)
                       (lowest = +34.0°C, highest = +43.0°C)

drivetemp-scsi-5-0
temp1:        +43.0°C  (low  = +10.0°C, high = +40.0°C)
                       (crit low =  +5.0°C, crit = +60.0°C)
                       (lowest = +38.0°C, highest = +46.0°C)

But this script:

#! /usr/bin/env bash

# Author: Thomas Debesse
# License: CC0 1.0

# This file also exist and can be used to fetch drive name:
# /sys/bus/scsi/devices/host*/target*/*/model
# but it seems to be limited to 16 chars in length and then
# does not contain the complete name, so it looks better to
# build a name database by iterating /dev/disk/by-id folder.
declare -A associative name_dict
for byid in $(find /dev/disk/by-id/ -mindepth 1 -maxdepth 1 -type l -name 'ata-*')
do
    block="$(basename "$(realpath "${byid}")")"
    # We can keep disk serial number by not cutting on '_'
    name="$(echo "${byid}" | cut -d'/' -f5 | cut -c5- | cut -d'_' -f1)"
    name_dict["${block}"]="${name}"
done

sensors --no-adapter 'drivetemp-*' \
| while IFS= read line
do
    if echo "${line}" | grep -q '^drivetemp-'
    then
        driver="$(echo "${line}" | cut -d'-' -f2)"
        major="$(echo "${line}" | cut -d'-' -f3)"
        minor="$(echo "${line}" | cut -d'-' -f4)"
        block="$(find "/sys/bus/${driver}/devices/host${major}/target${major}:${minor}:0/${major}:${minor}:0:0/block" -mindepth 1 -maxdepth 1 -type d -printf '%f')"

        name="${name_dict[${block}]}"

        if ! [ -z "${name}" ]
        then
            printf '%s\n' "${name}"
        else
            printf '%s\n' "${line}"
        fi
    else
        printf '%s\n' "${line}"
    fi
done

would output:

CT250MX500SSD4
temp1:        +45.0°C  (low  =  +0.0°C, high = +100.0°C)
                       (crit low =  +0.0°C, crit = +100.0°C)
                       (lowest = +36.0°C, highest = +60.0°C)

ST16000NE000-2RW103
temp1:        +44.0°C  (low  = +10.0°C, high = +40.0°C)
                       (crit low =  +5.0°C, crit = +60.0°C)
                       (lowest = +37.0°C, highest = +46.0°C)

ST16000NE000-2RW103
temp1:        +40.0°C  (low  = +10.0°C, high = +40.0°C)
                       (crit low =  +5.0°C, crit = +60.0°C)
                       (lowest = +34.0°C, highest = +41.0°C)

CT250MX500SSD4
temp1:        +43.0°C  (low  =  +0.0°C, high = +100.0°C)
                       (crit low =  +0.0°C, crit = +100.0°C)
                       (lowest = +35.0°C, highest = +51.0°C)

ST16000NE000-2RW103
temp1:        +41.0°C  (low  = +10.0°C, high = +40.0°C)
                       (crit low =  +5.0°C, crit = +60.0°C)
                       (lowest = +34.0°C, highest = +43.0°C)

ST16000NE000-2RW103
temp1:        +44.0°C  (low  = +10.0°C, high = +40.0°C)
                       (crit low =  +5.0°C, crit = +60.0°C)
                       (lowest = +38.0°C, highest = +46.0°C)

Note that it would also be possible to display the drive serial which is currently stripped from the demonstration script.

Implementing this is out of PR topic.

An user may also try to write disk names in a file in /etc/sensors.d (I haven't checked if it works).

UshakovVasilii commented 2 years ago

Thanks!

jonasmalacofilho commented 2 years ago

An user may also try to write disk names in a file in /etc/sensors.d (I haven't checked if it works).

That currently doesn't work because of lm-sensors/lm-sensors#230. (But, IMHO, it's still the better approach).

illwieckz commented 2 years ago

Ah tanks for the link! I tried to do create a sensors config on my end but I faced the same bug and I was going to report it. 😁

linusw commented 2 years ago

When drivetemp kernel module is loaded, the sensors utility can display drive temperatures. I noticed hddtemp may not report temperature when a drive is sleeping. (...) For some reasons this module is not loaded by default even not suggested by sensors-detect, but it works well.

I think the module would need to be loaded by udev scripts which are at times unique and per-distribution. If yo want to go the extra mile, patch to your favourite $dist to fix this.

This work so far is however amazing on its own :)