Hardware sensors using Go and lm-sensors

Using gosensors libary we can get hardware sensors values and monitor changes. Library is using lm-sensors and parses its output for easier use. There is also an option to load and parse content from log file.

Setup

  • Install lm-sensors with sudo apt get install lm-sensors
  • go get github.com/ssimunic/gosensors in your working directory

Example

Example output that was produced executing sensors command on Linux:

acpitz-virtual-0  
Adapter: Virtual device  
temp1:        +25.0°C  (crit = +107.0°C)

coretemp-isa-0000  
Adapter: ISA adapter  
Physical id 0:  +57.0°C  (high = +105.0°C, crit = +105.0°C)  
Core 0:         +57.0°C  (high = +105.0°C, crit = +105.0°C)  
Core 1:         +56.0°C  (high = +105.0°C, crit = +105.0°C)

dell_smm-virtual-0  
Adapter: Virtual device  
Processor Fan: 2800 RPM  
fan2:          2800 RPM  
CPU:            +59.0°C  
Other:          +50.0°C  
SODIMM:         +39.0°C  
GPU:            +49.0°C  

Below is a program that will print out JSON and temperature values for CPU and GPU.

package main

import (  
    "fmt"
    "github.com/ssimunic/gosensors"
)

func main() {  
    sensors, err := gosensors.NewFromSystem()
    // sensors, err := gosensors.NewFromFile("/path/to/log.txt")

    if err != nil {
        panic(err)
    }

    // Sensors implements Stringer interface,
    // so code below will print out JSON
    fmt.Println(sensors)

    // Also valid
    // fmt.Println("JSON:", sensors.JSON())

    // Iterate over chips
    for chip := range sensors.Chips {
        // Iterate over entries
        for key, value := range sensors.Chips[chip] {
            // If CPU or GPU, print out
            if key == "CPU" || key == "GPU" {
                fmt.Println(key, value)
            }
        }
    }
}

Example of generated JSON that is returned from JSON() or String() methods:

{
   "chips":{
      "acpitz-virtual-0":{
         "Adapter":"Virtual device",
         "temp1":"+25.0°C  (crit = +107.0°C)"
      },
      "coretemp-isa-0000":{
         "Adapter":"ISA adapter",
         "Core 0":"+76.0°C  (high = +105.0°C, crit = +105.0°C)",
         "Core 1":"+74.0°C  (high = +105.0°C, crit = +105.0°C)",
         "Physical id 0":"+76.0°C  (high = +105.0°C, crit = +105.0°C)"
      },
      "dell_smm-virtual-0":{
         "Adapter":"Virtual device",
         "CPU":"+65.0°C",
         "GPU":"+50.0°C",
         "Other":"+50.0°C",
         "Processor Fan":"2200 RPM",
         "SODIMM":"+39.0°C",
         "fan2":"2200 RPM"
      }
   }
}

To check periodically for temperature of GPU, we can use ticking channel and check it every second, as shown in example below.

package main

import (  
    "fmt"
    "time"

    "github.com/ssimunic/gosensors"
)

func getValue(sensors *gosensors.Sensors, target string) string {  
    for chip := range sensors.Chips {
        for key, value := range sensors.Chips[chip] {
            if key == target {
                return value
            }
        }
    }

    return ""
}

func main() {  
    for range time.Tick(time.Second) {
        sensors, err := gosensors.NewFromSystem()
        if err != nil {
            panic(err)
        }
        gpuTemp := getValue(sensors, "GPU")
        fmt.Println(gpuTemp)
    }
}

Silvio Simunic

Read more posts by this author.