From 05416bf4214d4b485a277fd3337002289378c7f5 Mon Sep 17 00:00:00 2001 From: Lukas Heiligenbrunner Date: Thu, 5 May 2022 09:56:08 +0000 Subject: [PATCH] SMART Temperature Readout --- main.go | 18 ++++++++++++++++++ smartdiskinfo.go | 35 ++++++++++++++++++++++++++++------- 2 files changed, 46 insertions(+), 7 deletions(-) diff --git a/main.go b/main.go index bf94859..6ac15ab 100644 --- a/main.go +++ b/main.go @@ -2,6 +2,7 @@ package main import ( "bytes" + "flag" "fmt" "log" "os" @@ -41,7 +42,24 @@ func main() { os.Exit(-1) } + tmpptr := flag.Bool("temp", false, "get temperatures") + + flag.Parse() + disks := getDisks() + + if *tmpptr { + fmt.Println("printing temperatures") + + for _, dev := range disks.Blockdevices { + path := fmt.Sprintf("/dev/%s", dev.Name) + + max, min, temp := getTemp(path) + fmt.Printf("%s temp: %d°C (max: %d°C, min: %d°C)\n", path, temp, max, min) + } + return + } + fmt.Printf("Running smart check on %d disks.\n", len(disks.Blockdevices)) for _, blockdevice := range disks.Blockdevices { path := fmt.Sprintf("/dev/%s", blockdevice.Name) diff --git a/smartdiskinfo.go b/smartdiskinfo.go index a1c84a3..5df8491 100644 --- a/smartdiskinfo.go +++ b/smartdiskinfo.go @@ -37,18 +37,18 @@ type Item struct { } `json:"raw"` } -func checkSmartAttributes(diskpath string, isSeagate bool, isHdd bool) { +type RawAttr struct { + AtaSmartAttr struct { + Table []Item `json:"table"` + } `json:"ata_smart_attributes"` +} + +func getSmartValues(diskpath string) *RawAttr { rawsmart := execSystem("smartctl", "-A", "-json", diskpath) if rawsmart == nil { fmt.Println("error while getting smart info") } - type RawAttr struct { - AtaSmartAttr struct { - Table []Item `json:"table"` - } `json:"ata_smart_attributes"` - } - var rawattr RawAttr err := json.Unmarshal(rawsmart, &rawattr) @@ -56,6 +56,27 @@ func checkSmartAttributes(diskpath string, isSeagate bool, isHdd bool) { if err != nil { fmt.Println(err) } + return &rawattr +} + +func getTemp(diskpath string) (uint32, uint32, uint32) { + rawattr := getSmartValues(diskpath) + temp := getItemValue(rawattr.AtaSmartAttr.Table, "Temperature_Celsius") + + // temp value is storead as following: + // 4bytes 4bytes 4bytes + // [----------------|----------------|---------------] + // max temp min temp curr temp + + max := temp >> 32 + min := (temp & 0xff00ff) >> 16 + currtemp := temp & 0x0000ff + + return uint32(max), uint32(min), uint32(currtemp) +} + +func checkSmartAttributes(diskpath string, isSeagate bool, isHdd bool) { + rawattr := getSmartValues(diskpath) rrerrrate := getItemValue(rawattr.AtaSmartAttr.Table, "Raw_Read_Error_Rate") // seagate hdds have a special way to represent their error rates