Open4

gopsutilのSensorsTemperatures()

ごずごず

shirou/gopsutil で温度が取れそうなので試してみる。

  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)
          }
  }

まずはMacで実行。

$ 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

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でよさそう。

ごずごず

Macでも取れたので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.19042 Build 19042
sensorKey: ACPI\ThermalZone\THM0_0, temperature: 55, sensorHigh:  0, sensorCritical:  0

管理者権限で実行するとそれっぽいものが取れた。1つだけ…
あってるかどうか確認するために、標準のコマンドで取ってみる。(これも管理者権限)

> wmic /namespace:\\root\wmi PATH MSAcpi_ThermalZoneTemperature get CurrentTemperature
Temperature
CurrentTemperature
3282

3282度な訳はない。
これはケルビンという値を10倍したものが取れるものらしい。
※ケルビンとは絶対温度の事で、摂氏を求めるには「ケルビン - 273.16」とすればよい
つまり、摂氏に直すと 3282 / 10 - 273.16 = 55.04 となる。
どうやらプログラムで取った値は正しそうだ。

THM0_0というのはCPUが増えれば増えそうなんだけど、そんなサーバみたいなWindowsマシンは手元にないので確認してないけど。

ごずごず

あとは実機の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

1000倍で取れるので合ってそう。

ごずごず

そういえばM2 Macになって動かしてなかったのでやってみたら何も取れなくなってた…
1つも取れないってどういうこと?Appleシリコンになったから違うところもあるかなと思ったけど全滅とはね。

darwin Standalone Workstation 14.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:  0, sensorHigh:  0, sensorCritical:  0
sensorKey: TB0T, temperature:  0, sensorHigh:  0, sensorCritical:  0
sensorKey: TB1T, temperature:  0, sensorHigh:  0, sensorCritical:  0
sensorKey: TB2T, temperature:  0, 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:  0, 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:  0, sensorHigh:  0, sensorCritical:  0