この記事は、Infocom Advent Calendar 2021 7日目の記事です。
あまり業務とは関係ないのですが、shirou/gopsutilを使ってサーバ情報を表示するアプリを作っている過程で、各種温度情報が取れるのが分かりました。 ただし、Mac、Linux、Windowsでそれぞれ違っていて、試行錯誤したので記録に残しておきます。
今年のアドベントカレンダーは全然埋まってないので、皆さん頑張ってw
Mac
開発をしているのがMacなのでまずはMacでとれるようにします。
個人で使っているMacbook Air(Intel) Mojaveです。
package main import ( "fmt" "os" "github.com/shirou/gopsutil/v3/host" ) func main() { h1, h2, h3, _ := host.PlatformInformation() fmt.Println(h1, h2, h3) t, err := host.SensorsTemperatures() if err != nil { fmt.Println(err.Error()) os.Exit(1) } for _, v := range t { fmt.Printf("sensorKey: %s, temperature: %2.0f, sensorHigh: %2.0f, sensorCritical: %2.0f\n", v.SensorKey, v.Temperature, v.High, v.Critical) } }
実行してみます。
$ go run main.go darwin Standalone Workstation 11.5.1 sensorKey: TA0P, temperature: 0, sensorHigh: 0, sensorCritical: 0 sensorKey: TA1P, temperature: 0, sensorHigh: 0, sensorCritical: 0 sensorKey: TC0D, temperature: 0, sensorHigh: 0, sensorCritical: 0 sensorKey: TC0H, temperature: 0, sensorHigh: 0, sensorCritical: 0 sensorKey: TC0P, temperature: 58, sensorHigh: 0, sensorCritical: 0 sensorKey: TB0T, temperature: 36, sensorHigh: 0, sensorCritical: 0 sensorKey: TB1T, temperature: 36, sensorHigh: 0, sensorCritical: 0 sensorKey: TB2T, temperature: 32, sensorHigh: 0, sensorCritical: 0 sensorKey: TB3T, temperature: 0, sensorHigh: 0, sensorCritical: 0 sensorKey: TG0D, temperature: 0, sensorHigh: 0, sensorCritical: 0 sensorKey: TG0H, temperature: 0, sensorHigh: 0, sensorCritical: 0 sensorKey: TG0P, temperature: 0, sensorHigh: 0, sensorCritical: 0 sensorKey: TH0P, temperature: 0, sensorHigh: 0, sensorCritical: 0 sensorKey: TM0S, temperature: 0, sensorHigh: 0, sensorCritical: 0 sensorKey: TM0P, temperature: 54, sensorHigh: 0, sensorCritical: 0 sensorKey: TN0H, temperature: 0, sensorHigh: 0, sensorCritical: 0 sensorKey: TN0D, temperature: 0, sensorHigh: 0, sensorCritical: 0 sensorKey: TN0P, temperature: 0, sensorHigh: 0, sensorCritical: 0 sensorKey: TI0P, temperature: 0, sensorHigh: 0, sensorCritical: 0 sensorKey: TI1P, temperature: 0, sensorHigh: 0, sensorCritical: 0 sensorKey: TW0P, temperature: 49, sensorHigh: 0, sensorCritical: 0
TA0Pとかは、smc_darwin.hで定義されているようです。
https://github.com/shirou/gopsutil/blob/master/v3/host/smc_darwin.h
#define AMBIENT_AIR_0 "TA0P" #define AMBIENT_AIR_1 "TA1P" #define CPU_0_DIODE "TC0D" #define CPU_0_HEATSINK "TC0H" #define CPU_0_PROXIMITY "TC0P" #define ENCLOSURE_BASE_0 "TB0T" #define ENCLOSURE_BASE_1 "TB1T" #define ENCLOSURE_BASE_2 "TB2T" #define ENCLOSURE_BASE_3 "TB3T" #define GPU_0_DIODE "TG0D" #define GPU_0_HEATSINK "TG0H" #define GPU_0_PROXIMITY "TG0P" #define HARD_DRIVE_BAY "TH0P" #define MEMORY_SLOT_0 "TM0S" #define MEMORY_SLOTS_PROXIMITY "TM0P" #define NORTHBRIDGE "TN0H" #define NORTHBRIDGE_DIODE "TN0D" #define NORTHBRIDGE_PROXIMITY "TN0P" #define THUNDERBOLT_0 "TI0P" #define THUNDERBOLT_1 "TI1P" #define WIRELESS_MODULE "TW0P"
CPU関係では、TC0DとTC0Hは取れておらず、TC0Pだけ取れているようです。
PROXIMITYは近い・近接的な意味のようなのでCPU温度を見るならとりあえずTC0Pでよいのかなと思いました。
Windows
お仕事ではWindowsサーバを使うのでこちらも取得してみます。
とりあえず同じコードを実行してみます。
C:\home\gozu\go\src\github.com\gozuk16\cputemp>go run main.go Microsoft Windows 10 Pro Standalone Workstation 10.0.19042 Build 19042 例外が発生しました。 (アクセスは拒否されました ) exit status 1
どうやらWindowsでは管理者権限が必要みたいですね。
管理者権限で実行してみます。
C:\home\gozu\go\src\github.com\gozuk16\cputemp>go run main.go Microsoft Windows 10 Pro Standalone Workstation 10.0.19043 Build 19043 sensorKey: ACPI\ThermalZone\THM0_0, temperature: 40, sensorHigh: 0, sensorCritical: 0
ACPI\ThermalZone\THM0_0というのが1つだけ取れました。
これはWMIの情報のようです。wmicで確認のため同じものを取得してみます。 (この場合も管理者権限が必要です)
> wmic /namespace:\\root\wmi PATH MSAcpi_ThermalZoneTemperature get CurrentTemperature Temperature CurrentTemperature 3132
3132度???
いやいやそんなわけない。
これはケルビンという値を10倍したものが取れるものらしい。
※ケルビンとは絶対温度の事で、摂氏を求めるには「ケルビン - 273.16」とすればよい
つまり、摂氏に直すと 3132 / 10 - 273.16 = 40.04 となります。
どうやらプログラムで取った値は正しそうですね。
管理者権限が必要なのは面倒くさいなぁ。
Linux
VMじゃない実機のLinuxだとラズパイがあるのでやってみました。
Raspberry Pi OS 64bit版にしてあるのですが、どうやらaptで入るGoは1.11という古いバージョンなのでダウンロードして入れます。
$ wget https://golang.org/dl/go1.16.7.linux-arm64.tar.gz $ sudo tar -C /usr/local -xzf go1.16.7.linux-arm64.tar.gz $ vi .bashrc # ↓を追加 export PATH=$PATH:/usr/local/go/bin $ . .bashrc $ go version go version go1.16.7 linux/arm64
同じものを実行します。
$ go run main.go raspbian debian 10.10 sensorKey: cpu_thermal, temperature: 62 sensorHigh: 0, sensorCritical: 0
cpu_thermalというのが1つ取れました。
確認のためコマンドでたたいてみます。
$ cat /sys/class/thermal/thermal_zone0/temp 62322
62322度な訳は無いw
これは1000倍で取れるそうなのであってます。