finished temperature querying
This commit is contained in:
1 parent
b1d4f3565d
commit
be44d008c7
7 files changed
+168
-3
No files matched your search
@@ -0,0 +1,43 @@
|
||||
//go:build linux
|
||||
|
||||
package temperature
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"os"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
func getLinuxCPUTemperature() (TemperatureInformation, error) {
|
||||
tempFile, err := os.Open("/sys/class/thermal/thermal_zone0/temp")
|
||||
if err != nil {
|
||||
fmt.Printf("Could not find /sys/class/thermal/thermal_zone0/temp. Trying /sys/class/hwmon/hwmon0/temp1_input...")
|
||||
tempFile, err = os.Open("/sys/class/hwmon/hwmon0/temp1_input")
|
||||
if err != nil {
|
||||
return TemperatureInformation{0, false}, fmt.Errorf("Couldn't find temperature information. System is unsupported.")
|
||||
}
|
||||
}
|
||||
defer tempFile.Close()
|
||||
|
||||
fileReader := bufio.NewScanner(tempFile)
|
||||
|
||||
var celsius float64
|
||||
|
||||
fileReader.Scan()
|
||||
if fileReader.Err() != nil {
|
||||
return TemperatureInformation{0, false}, fmt.Errorf("Could not read temperature.")
|
||||
}
|
||||
|
||||
data := fileReader.Text()
|
||||
celsius, _ = strconv.ParseFloat(data, 64)
|
||||
|
||||
return TemperatureInformation{
|
||||
Celsius: celsius / 1000.0,
|
||||
Supported: true,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func GetTemperatureInformation() (TemperatureInformation, error) {
|
||||
return getLinuxCPUTemperature()
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package temperature
|
||||
|
||||
type TemperatureInformation struct {
|
||||
Celsius float64
|
||||
|
||||
Supported bool
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
//go:build windows
|
||||
|
||||
package temperature
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/yusufpapurcu/wmi"
|
||||
)
|
||||
|
||||
type LHMSensor struct {
|
||||
Value float32
|
||||
}
|
||||
|
||||
type LHMNode struct {
|
||||
Text string `json:"Text"`
|
||||
Value string `json:"Value"`
|
||||
Children []LHMNode `json:"Children"`
|
||||
}
|
||||
|
||||
type MSAcpiThermalZone struct {
|
||||
CurrentTemperature uint32
|
||||
}
|
||||
|
||||
func findCPUTemp(node LHMNode) string {
|
||||
if strings.Contains(node.Text, "CPU Package") && strings.Contains(node.Value, "°C") {
|
||||
return node.Value
|
||||
}
|
||||
|
||||
for _, child := range node.Children {
|
||||
if val := findCPUTemp(child); val != "" {
|
||||
return val
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func getWinCPUTemperature() TemperatureInformation {
|
||||
// check for preexisting monitoring tools
|
||||
var lhm []LHMSensor
|
||||
lhmQuery := "SELECT Value FROM Sensor WHERE SensorType = 'Temperature' AND Name LIKE '%CPU Package%'"
|
||||
if err := wmi.QueryNamespace(lhmQuery, &lhm, `root\OpenHardwareMonitor`); err == nil && len(lhm) > 0 {
|
||||
return TemperatureInformation{Celsius: float64(lhm[0].Value), Supported: true}
|
||||
} else {
|
||||
// Try LHM local webserver
|
||||
client := http.Client{Timeout: 1 * time.Second}
|
||||
resp, err := client.Get("http://localhost:8085/data.json")
|
||||
if err == nil {
|
||||
defer resp.Body.Close()
|
||||
var root LHMNode
|
||||
if json.NewDecoder(resp.Body).Decode(&root) == nil {
|
||||
tempStr := findCPUTemp(root)
|
||||
if tempStr != "" {
|
||||
var temp float64
|
||||
fmt.Sscanf(tempStr, "%f", &temp)
|
||||
return TemperatureInformation{Celsius: temp, Supported: true}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// check native ACPI
|
||||
var acpi []MSAcpiThermalZone
|
||||
acpiQuery := "SELECT CurrentTemperature FROM MSAcpi_ThermalZoneTemperature"
|
||||
if err := wmi.QueryNamespace(acpiQuery, &acpi, `root\wmi`); err == nil && len(acpi) > 0 {
|
||||
kelvinTenths := float64(acpi[0].CurrentTemperature)
|
||||
celsius := (kelvinTenths / 10.0) - 273.15
|
||||
|
||||
// Discard known fake motherboard values
|
||||
if celsius != 27.8 && celsius != 29.8 && celsius != 24.05 && celsius > 0 && celsius < 150 {
|
||||
return TemperatureInformation{Celsius: celsius, Supported: true}
|
||||
}
|
||||
}
|
||||
|
||||
return TemperatureInformation{0, false} // unsupported
|
||||
}
|
||||
|
||||
// This is really finicky and is rarely working well due to windows
|
||||
// temperature information being a RING0 feature. Maybe later this
|
||||
// can be improved upon, but for now it's good enough as it is now.
|
||||
func GetTemperatureInformation() (TemperatureInformation, error) {
|
||||
return getWinCPUTemperature(), nil
|
||||
}
|
||||
Reference in new issue
Block a user