diff options
author | Sean E. Russell <ser@ser1.net> | 2020-06-09 09:03:58 -0500 |
---|---|---|
committer | Sean E. Russell <ser@ser1.net> | 2020-06-09 09:54:10 -0500 |
commit | 1181b94bd228f5f081d49f6c7c9a9ee9c26557ed (patch) | |
tree | 6c56836eefc5e5ec256ff8a3adfb674562a28f29 | |
parent | 5590679cb4cc4dcd6ccb4694780eda38326bc4c5 (diff) |
Closes #131, SMC GPL issue on OSX; consequently removes need to CGO in darwin.v4.0.1
-rw-r--r-- | .github/workflows/build.yml | 2 | ||||
-rw-r--r-- | .gitignore | 2 | ||||
-rw-r--r-- | devices/data/smc.tsv | 162 | ||||
-rw-r--r-- | devices/smc.go | 235 | ||||
-rw-r--r-- | devices/temp.go | 4 | ||||
-rw-r--r-- | devices/temp_darwin.go | 85 | ||||
-rw-r--r-- | devices/temp_darwin_test.go | 45 | ||||
-rw-r--r-- | devices/temp_linux.go | 28 | ||||
-rw-r--r-- | devices/temp_nix.go | 30 | ||||
-rw-r--r-- | docs/releasing.md | 5 | ||||
-rw-r--r-- | go.mod | 1 | ||||
-rw-r--r-- | go.sum | 4 |
12 files changed, 542 insertions, 61 deletions
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 6de087d..6ed52bd 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -19,4 +19,4 @@ jobs: env: SRCPATH: ./cmd/gotop with: - args: darwin/amd64/1 linux/amd64 linux/386 linux/arm64 linux/arm7 linux/arm6 linux/arm5 windows/amd64 windows/386 freebsd/amd64 freebsd/386 + args: darwin/amd64 linux/amd64 linux/386 linux/arm64 linux/arm7 linux/arm6 linux/arm5 windows/amd64 windows/386 freebsd/amd64 freebsd/386 @@ -11,3 +11,5 @@ dist/ build/gotop_* build.log + +tmp/ diff --git a/devices/data/smc.tsv b/devices/data/smc.tsv new file mode 100644 index 0000000..f6ff37b --- /dev/null +++ b/devices/data/smc.tsv @@ -0,0 +1,162 @@ +"TCXC" "PECI CPU" +"TCXc" "PECI CPU" +"TC0P" "CPU 1 Proximity" +"TC0H" "CPU 1 Heatsink" +"TC0D" "CPU 1 Package" +"TC0E" "CPU 1" +"TC0F" "CPU 1" +"TC1C" "CPU Core 1" +"TC2C" "CPU Core 2" +"TC3C" "CPU Core 3" +"TC4C" "CPU Core 4" +"TC5C" "CPU Core 5" +"TC6C" "CPU Core 6" +"TC7C" "CPU Core 7" +"TC8C" "CPU Core 8" +"TCAH" "CPU 1 Heatsink Alt." +"TCAD" "CPU 1 Package Alt." +"TC1P" "CPU 2 Proximity" +"TC1H" "CPU 2 Heatsink" +"TC1D" "CPU 2 Package" +"TC1E" "CPU 2" +"TC1F" "CPU 2" +"TCBH" "CPU 2 Heatsink Alt." +"TCBD" "CPU 2 Package Alt." +"TCSC" "PECI SA" +"TCSc" "PECI SA" +"TCSA" "PECI SA" +"TCGC" "PECI GPU" +"TCGc" "PECI GPU" +"TG0P" "GPU Proximity" +"TG0D" "GPU Die" +"TG1D" "GPU Die" +"TG0H" "GPU Heatsink" +"TG1H" "GPU Heatsink" +"Ts0S" "Memory Proximity" +"TM0P" "Mem Bank A1" +"TM1P" "Mem Bank A2" +"TM8P" "Mem Bank B1" +"TM9P" "Mem Bank B2" +"TM0S" "Mem Module A1" +"TM1S" "Mem Module A2" +"TM8S" "Mem Module B1" +"TM9S" "Mem Module B2" +"TN0D" "Northbridge Die" +"TN0P" "Northbridge Proximity 1" +"TN1P" "Northbridge Proximity 2" +"TN0C" "MCH Die" +"TN0H" "MCH Heatsink" +"TP0D" "PCH Die" +"TPCD" "PCH Die" +"TP0P" "PCH Proximity" +"TA0P" "Airflow 1" +"TA1P" "Airflow 2" +"Th0H" "Heatpipe 1" +"Th1H" "Heatpipe 2" +"Th2H" "Heatpipe 3" +"Tm0P" "Mainboard Proximity" +"Tp0P" "Powerboard Proximity" +"Ts0P" "Palm Rest" +"Tb0P" "BLC Proximity" +"TL0P" "LCD Proximity" +"TW0P" "Airport Proximity" +"TH0P" "HDD Bay 1" +"TH1P" "HDD Bay 2" +"TH2P" "HDD Bay 3" +"TH3P" "HDD Bay 4" +"TO0P" "Optical Drive" +"TB0T" "Battery TS_MAX" +"TB1T" "Battery 1" +"TB2T" "Battery 2" +"TB3T" "Battery" +"Tp0P" "Power Supply 1" +"Tp0C" "Power Supply 1 Alt." +"Tp1P" "Power Supply 2" +"Tp1C" "Power Supply 2 Alt." +"Tp2P" "Power Supply 3" +"Tp3P" "Power Supply 4" +"Tp4P" "Power Supply 5" +"Tp5P" "Power Supply 6" +"TS0C" "Expansion Slots" +"TA0S" "PCI Slot 1 Pos 1" +"TA1S" "PCI Slot 1 Pos 2" +"TA2S" "PCI Slot 2 Pos 1" +"TA3S" "PCI Slot 2 Pos 2" +"VC0C" "CPU Core 1" +"VC1C" "CPU Core 2" +"VC2C" "CPU Core 3" +"VC3C" "CPU Core 4" +"VC4C" "CPU Core 5" +"VC5C" "CPU Core 6" +"VC6C" "CPU Core 7" +"VC7C" "CPU Core 8" +"VV1R" "CPU VTT" +"VG0C" "GPU Core" +"VM0R" "Memory" +"VN1R" "PCH" +"VN0C" "MCH" +"VD0R" "Mainboard S0 Rail" +"VD5R" "Mainboard S5 Rail" +"VP0R" "12V Rail" +"Vp0C" "12V Vcc" +"VV2S" "Main 3V" +"VR3R" "Main 3.3V" +"VV1S" "Main 5V" +"VH05" "Main 5V" +"VV9S" "Main 12V" +"VD2R" "Main 12V" +"VV7S" "Auxiliary 3V" +"VV3S" "Standby 3V" +"VV8S" "Standby 5V" +"VeES" "PCIe 12V" +"VBAT" "Battery" +"Vb0R" "CMOS Battery" +"IC0C" "CPU Core" +"IC1C" "CPU VccIO" +"IC2C" "CPU VccSA" +"IC0R" "CPU Rail" +"IC5R" "CPU DRAM" +"IC8R" "CPU PLL" +"IC0G" "CPU GFX" +"IC0M" "CPU Memory" +"IG0C" "GPU Rail" +"IM0C" "Memory Controller" +"IM0R" "Memory Rail" +"IN0C" "MCH" +"ID0R" "Mainboard S0 Rail" +"ID5R" "Mainboard S5 Rail" +"IO0R" "Misc. Rail" +"IB0R" "Battery Rail" +"IPBR" "Charger BMON" +"PC0C" "CPU Core 1" +"PC1C" "CPU Core 2" +"PC2C" "CPU Core 3" +"PC3C" "CPU Core 4" +"PC4C" "CPU Core 5" +"PC5C" "CPU Core 6" +"PC6C" "CPU Core 7" +"PC7C" "CPU Core 8" +"PCPC" "CPU Cores" +"PCPG" "CPU GFX" +"PCPD" "CPU DRAM" +"PCTR" "CPU Total" +"PCPL" "CPU Total" +"PC1R" "CPU Rail" +"PC5R" "CPU S0 Rail" +"PGTR" "GPU Total" +"PG0R" "GPU Rail" +"PM0R" "Memory Rail" +"PN0C" "MCH" +"PN1R" "PCH Rail" +"PC0R" "Mainboard S0 Rail" +"PD0R" "Mainboard S0 Rail" +"PD5R" "Mainboard S5 Rail" +"PH02" "Main 3.3V Rail" +"PH05" "Main 5V Rail" +"Pp0R" "12V Rail" +"PD2R" "Main 12V Rail" +"PO0R" "Misc. Rail" +"PBLC" "Battery Rail" +"PB0R" "Battery Rail" +"PDTR" "DC In Total" +"PSTR" "System Total" diff --git a/devices/smc.go b/devices/smc.go new file mode 100644 index 0000000..4701a07 --- /dev/null +++ b/devices/smc.go @@ -0,0 +1,235 @@ +// Code generated by go-bindata. +// sources: +// data/smc.tsv +// DO NOT EDIT! + +package devices + +import ( + "bytes" + "compress/gzip" + "fmt" + "io" + "io/ioutil" + "os" + "path/filepath" + "strings" + "time" +) + +func bindataRead(data []byte, name string) ([]byte, error) { + gz, err := gzip.NewReader(bytes.NewBuffer(data)) + if err != nil { + return nil, fmt.Errorf("Read %q: %v", name, err) + } + + var buf bytes.Buffer + _, err = io.Copy(&buf, gz) + clErr := gz.Close() + + if err != nil { + return nil, fmt.Errorf("Read %q: %v", name, err) + } + if clErr != nil { + return nil, err + } + + return buf.Bytes(), nil +} + +type asset struct { + bytes []byte + info os.FileInfo +} + +type bindataFileInfo struct { + name string + size int64 + mode os.FileMode + modTime time.Time +} + +func (fi bindataFileInfo) Name() string { + return fi.name +} +func (fi bindataFileInfo) Size() int64 { + return fi.size +} +func (fi bindataFileInfo) Mode() os.FileMode { + return fi.mode +} +func (fi bindataFileInfo) ModTime() time.Time { + return fi.modTime +} +func (fi bindataFileInfo) IsDir() bool { + return false +} +func (fi bindataFileInfo) Sys() interface{} { + return nil +} + +var _smcTsv = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x74\x95\xc1\x72\xab\x3a\x0f\xc7\xd7\x3d\x4f\xc1\xf0\x00\x1d\x4c\x92\x36\x67\x09\xa6\x05\x66\x42\xa2\x09\x29\x5f\x77\xdf\x10\xca\x6d\x99\x43\x02\x03\xf4\x9e\xe6\xed\xef\x58\xc6\xc6\x36\x64\xe9\x9f\x24\xdb\x92\xfe\xb2\xed\x13\x7d\xa7\xf6\x83\x0d\x2f\x34\xb6\x28\xbc\xd9\xbf\x18\x29\x4c\xe2\x80\xfd\x60\x53\x78\xb3\x88\x05\x5d\xf3\x53\x5d\xaa\xe1\xc6\x0d\x91\x34\x44\x65\x3e\xf4\xd5\xf5\x0f\xe7\xc1\x14\x90\x17\x7f\xf2\xcf\x92\xe3\x17\x81\xf9\xf2\x55\x5b\x12\x3a\x2e\x69\xd3\x95\x23\x73\x35\xe6\x22\x5b\x69\x6c\x85\x6c\xad\xb1\x35\xb2\x8d\xc6\x36\xc8\x9e\x34\xf6\x84\xec\x59\x63\xcf\xc8\xb6\x1a\xdb\x22\xf3\xe6\xc9\x5a\x5e\x3d\x3c\x72\xe3\x2c\xe3\xc9\x46\x44\xf9\x5c\xa3\x7c\x24\x92\x06\xad\x7c\x24\x98\x02\x94\xf2\x11\x51\x3e\x5e\x07\xf2\xaa\x2d\xfd\xf9\x66\xd3\x15\xfc\xd9\x8e\x93\x2d\x95\x0a\x48\x3d\x0e\x0a\x13\x78\x06\x08\x65\x48\x38\x4a\x24\x2c\x0c\x12\xa2\x68\x42\x78\xd3\x73\x0e\x51\x1a\x0c\x07\x15\x66\x15\x12\x13\xa0\xa8\x18\x50\x6b\x12\x92\x25\xda\x3b\xa9\xfd\x60\x27\xe5\xa5\xe9\x6e\xfa\x39\x09\x1e\x9f\x94\x17\xcb\xcf\x59\x21\x50\x4e\x09\xd1\x21\x16\x2e\xd9\x6a\xd0\xe7\x9e\xbf\x75\xc8\x3d\xc5\x69\x56\xd2\x7c\x7c\xd7\xa5\xdc\xd5\xc4\xe3\xbe\x06\x16\x3b\x9b\x18\xbd\xf7\x58\x97\x7d\xd3\x0d\x5f\xe7\xae\xfa\xf8\x2c\x45\x39\xf6\x98\x88\x6a\x90\x79\xf2\x19\xd9\x93\xfb\x0e\xe3\xd6\xac\x5b\x09\x8d\xa6\x2d\xa3\x11\xa8\xb5\x04\xbc\x01\x4c\x6e\x40\x4d\x80\x57\x61\x40\x2b\xb5\x87\xd8\xab\xba\x7f\xea\xe6\x2f\xbf\x93\x47\x54\x84\xb7\xf8\xc2\x43\xd9\x81\x6d\xd5\x8e\xe3\xfd\x45\x34\xc6\xfd\x5c\x8d\xe1\x78\x5f\x78\x33\xf3\xea\x7a\x6e\xf2\xee\x43\x3f\xbe\xe5\xb7\x6a\xfe\x96\xdd\x82\xb5\xe7\xd6\xbc\xbe\x58\xc7\xb2\x1f\x18\x3a\x23\xf2\x77\x54\xf7\xdc\x21\xde\xd1\x40\xc7\xff\x13\xd9\xb5\x4d\x37\xe8\xa6\x08\x4d\x51\x10\x58\x7e\x3e\x36\x23\x22\x2a\xc2\x84\x22\x57\x45\x98\x4f\xb4\x52\x11\xbe\x56\x07\xdc\xeb\xd0\x0e\x55\x91\xd7\x56\xd0\x55\xff\x62\xc9\x7d\xe7\xc4\xee\x9a\x0f\x43\xd9\xdd\xac\x53\xfa\xff\xc4\x7b\x47\x4e\x54\x8e\x47\xfb\xae\x8a\xf0\x68\x7f\xa5\x20\xa3\x56\x56\xfa\xdd\xb6\xf5\x18\xdb\xa2\x44\x74\x2e\x1f\x88\x96\xcc\x82\x5c\xce\x67\x41\xee\x14\xe4\xce\x82\x30\xf5\x76\x35\xe3\x98\x7f\xbb\x9e\x71\x7c\xb1\xdb\xcd\x8c\xe3\xab\x9d\xe2\x8d\x5f\x7e\xda\xfc\xda\x57\xcd\xd5\x4a\xeb\x66\xe8\xb9\x1a\x53\x14\x69\x8c\x88\x3d\xc7\x4d\x2f\x44\xb9\x60\xc1\x4c\x3c\x57\xb3\xb8\x4a\xcc\x6a\xc1\xc2\x62\x32\xea\xcc\xbe\xab\xcc\xf8\xc2\xb8\x9f\x3b\xfb\xae\x32\xe3\x0b\x5b\x23\x5b\xcf\xbe\xab\xcc\xf8\xc2\x9e\x90\x3d\xcd\xbe\xab\xcc\xf8\xc2\xd8\x77\x95\x65\xe4\x38\xb2\xec\x74\x62\x20\xc4\x0b\x87\xa3\x13\x23\x89\x73\x94\xaf\x27\x5b\xef\x31\x04\x68\x84\x0b\xf1\x6a\xb0\x45\xc0\x3d\xe5\x00\xa6\x8e\x75\xcc\xab\x1a\x4d\x1b\xc3\xb4\x91\x26\xc0\x28\xe2\x66\x92\x70\x9d\x31\x92\x15\x05\xde\x12\x2b\xcf\xa2\xad\x55\xc6\xc0\x71\x75\x94\xe0\x91\xa3\x8c\x48\x9f\x0d\x82\xc8\xd9\xe8\x20\xfb\x2d\x3d\x88\x8b\x24\x70\x8f\x06\xc9\x9e\x99\x8f\xf7\xfd\x53\xd5\x55\xde\xdd\xc6\xe3\x32\xec\x6f\x3a\xe4\xd7\x8f\xb3\x64\x5b\x95\xf1\x13\xca\x97\x51\x07\xa5\xd8\xcf\xf7\xf4\xd9\xca\xce\x98\x2d\x4d\x0e\xa9\x35\xd1\x58\x97\x09\x12\x29\x92\xac\x28\xe2\x03\x22\x57\x41\xf8\xc5\xc6\xd4\x11\xed\x1b\x6b\x17\xd3\x8d\x20\xc1\xd1\x4b\x90\x6c\x05\x81\xdd\x8e\x07\x85\x23\x08\x5f\xdf\x39\x48\x46\x20\xbb\x1c\x4f\x3a\x10\x3b\x27\xbc\xd5\xfc\x17\xa5\xcd\x75\xe8\x9a\xba\x2e\x3b\x6e\x9a\x24\x22\xfd\x55\x69\xc4\xf7\xa5\x11\xdf\x97\x46\x7c\xe0\x51\x55\x5f\x3c\x4a\xe6\x23\x13\x0f\x98\xa0\xe0\x63\x92\x5f\x79\xf7\x59\x76\x96\x9f\x1c\xf6\xf6\x2f\x1b\x16\xa6\x0f\x16\xa6\x0f\x16\xa6\x0f\x16\xa6\x0f\x16\xa6\x0f\x16\xa6\x0f\x16\xa6\x0f\x16\xa6\x0f\x28\xa8\xac\xe7\x48\x6f\x0e\x50\x08\xf4\x86\x02\x3d\x89\x86\x9e\x9a\x21\xaf\xb9\xd3\x6e\x86\x88\x21\x0d\x98\xa4\x31\x55\x1f\x42\xdc\x2c\x54\x23\x43\xe7\xa8\xb7\x1e\x96\xfa\x0b\x6a\x7f\x41\x3e\x0a\xd3\x69\x77\x3b\x0e\xf7\xc5\x00\xf7\xc5\x00\x91\xe3\xaa\x33\xaf\x70\x65\xce\x25\x6d\xcd\x57\x05\xf4\x61\x97\x78\x41\x63\xe0\xef\xe8\x5c\x63\xb0\xa8\x3c\x08\xb0\x80\x01\xb5\xe2\xeb\x54\xc2\x14\x61\x7a\xeb\x87\xf2\x22\xe8\x7f\x01\x00\x00\xff\xff\x1d\x32\xff\xb6\x46\x0d\x00\x00") + +func smcTsvBytes() ([]byte, error) { + return bindataRead( + _smcTsv, + "smc.tsv", + ) +} + +func smcTsv() (*asset, error) { + bytes, err := smcTsvBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "smc.tsv", size: 3398, mode: os.FileMode(420), modTime: time.Unix(1591711965, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +// Asset loads and returns the asset for the given name. +// It returns an error if the asset could not be found or +// could not be loaded. +func Asset(name string) ([]byte, error) { + cannonicalName := strings.Replace(name, "\\", "/", -1) + if f, ok := _bindata[cannonicalName]; ok { + a, err := f() + if err != nil { + return nil, fmt.Errorf("Asset %s can't read by error: %v", name, err) + } + return a.bytes, nil + } + return nil, fmt.Errorf("Asset %s not found", name) +} + +// MustAsset is like Asset but panics when Asset would return an error. +// It simplifies safe initialization of global variables. +func MustAsset(name string) []byte { + a, err := Asset(name) + if err != nil { + panic("asset: Asset(" + name + "): " + err.Error()) + } + + return a +} + +// AssetInfo loads and returns the asset info for the given name. +// It returns an error if the asset could not be found or +// could not be loaded. +func AssetInfo(name string) (os.FileInfo, error) { + cannonicalName := strings.Replace(name, "\\", "/", -1) + if f, ok := _bindata[cannonicalName]; ok { + a, err := f() + if err != nil { + return nil, fmt.Errorf("AssetInfo %s can't read by error: %v", name, err) + } + return a.info, nil + } + return nil, fmt.Errorf("AssetInfo %s not found", name) +} + +// AssetNames returns the names of the assets. +func AssetNames() []string { + names := make([]string, 0, len(_bindata)) + for name := range _bindata { + names = append(names, name) + } + return names +} + +// _bindata is a table, holding each asset generator, mapped to its name. +var _bindata = map[string]func() (*asset, error){ + "smc.tsv": smcTsv, +} + +// AssetDir returns the file names below a certain +// directory embedded in the file by go-bindata. +// For example if you run go-bindata on data/... and data contains the +// following hierarchy: +// data/ +// foo.txt +// img/ +// a.png +// b.png +// then AssetDir("data") would return []string{"foo.txt", "img"} +// AssetDir("data/img") would return []string{"a.png", "b.png"} +// AssetDir("foo.txt") and AssetDir("notexist") would return an error +// AssetDir("") will return []string{"data"}. +func AssetDir(name string) ([]string, error) { + node := _bintree + if len(name) != 0 { + cannonicalName := strings.Replace(name, "\\", "/", -1) + pathList := strings.Split(cannonicalName, "/") + for _, p := range pathList { + node = node.Children[p] + if node == nil { + return nil, fmt.Errorf("Asset %s not found", name) + } + } + } + if node.Func != nil { + return nil, fmt.Errorf("Asset %s not found", name) + } + rv := make([]string, 0, len(node.Children)) + for childName := range node.Children { + rv = append(rv, childName) + } + return rv, nil +} + +type bintree struct { + Func func() (*asset, error) + Children map[string]*bintree +} +var _bintree = &bintree{nil, map[string]*bintree{ + "smc.tsv": &bintree{smcTsv, map[string]*bintree{}}, +}} + +// RestoreAsset restores an asset under the given directory +func RestoreAsset(dir, name string) error { + data, err := Asset(name) + if err != nil { + return err + } + info, err := AssetInfo(name) + if err != nil { + return err + } + err = os.MkdirAll(_filePath(dir, filepath.Dir(name)), os.FileMode(0755)) + if err != nil { + return err + } + err = ioutil.WriteFile(_filePath(dir, name), data, info.Mode()) + if err != nil { + return err + } + err = os.Chtimes(_filePath(dir, name), info.ModTime(), info.ModTime()) + if err != nil { + return err + } + return nil +} + +// RestoreAssets restores an asset under the given directory recursively +func RestoreAssets(dir, name string) error { + children, err := AssetDir(name) + // File + if err != nil { + return RestoreAsset(dir, name) + } + // Dir + for _, child := range children { + err = RestoreAssets(dir, filepath.Join(name, child)) + if err != nil { + return err + } + } + return nil +} + +func _filePath(dir, name string) string { + cannonicalName := strings.Replace(name, "\\", "/", -1) + return filepath.Join(append([]string{dir}, strings.Split(cannonicalName, "/")...)...) +} + diff --git a/devices/temp.go b/devices/temp.go index 010e7ad..247075a 100644 --- a/devices/temp.go +++ b/devices/temp.go @@ -1,9 +1,13 @@ package devices +//go:generate go-bindata -pkg devices -prefix data -o smc.go data + import ( "log" ) +// TODO add thermal history graph. Update when something changes? + var tempUpdates []func(map[string]int) map[string]error func RegisterTemp(update func(map[string]int) map[string]error) { diff --git a/devices/temp_darwin.go b/devices/temp_darwin.go index 1111943..ecdc9f1 100644 --- a/devices/temp_darwin.go +++ b/devices/temp_darwin.go @@ -2,45 +2,74 @@ package devices -// TODO gopsutil team reports this is not needed; try getting rid of this dep -import smc "github.com/xxxserxxx/iSMC" +import ( + "bytes" + "encoding/csv" + "github.com/shirou/gopsutil/host" + "io" +) -func init() { - RegisterTemp(update) - RegisterDeviceList(Temperatures, devs, defs) - ts = make(map[string]float32) -} - -var ts map[string]float32 - -func update(temps map[string]int) map[string]error { - err := smc.GetTemp(ts) +// All possible thermometers +func devs() []string { + // Did we already populate the sensorMap? + if sensorMap != nil { + return defs() + } + // Otherwise, get the sensor data from the system & filter it + ids := loadIDs() + sensors, err := host.SensorsTemperatures() if err != nil { - return map[string]error{"temps": err} + // FIXME log an error here + return []string{} } - for k, v := range ts { - if _, ok := temps[k]; ok { - temps[k] = int(v + 0.5) + rv := make([]string, 0, len(sensors)) + sensorMap = make(map[string]string) + for _, sensor := range sensors { + // 0-value sensors are not implemented + if sensor.Temperature == 0 { + continue + } + if label, ok := ids[sensor.SensorKey]; ok { + sensorMap[sensor.SensorKey] = label + rv = append(rv, label) } } - return nil + return rv } -func devs() []string { - rv := make([]string, len(smc.AppleTemp)) - for i, v := range smc.AppleTemp { - rv[i] = v.Desc +// Only the ones filtered +func defs() []string { + rv := make([]string, 0, len(sensorMap)) + for _, val := range sensorMap { + rv = append(rv, val) } return rv } -func defs() []string { - // CPU 0 CPU 1 GPU Memory Disk - ids := map[string]bool{"TC0P": true, "TC1P": true, "TG0P": true, "Ts0S": true, "TH0P": true} - rv := make([]string, 0, len(ids)) - for _, v := range smc.AppleTemp { - if ids[v.Key] { - rv = append(rv, v.Desc) +// loadIDs parses the embedded smc.tsv data that maps Darwin SMC +// sensor IDs to their human-readable labels into an array and returns the +// array. The array keys are the 4-letter sensor keys; the values are the +// human labels. +func loadIDs() map[string]string { + rv := make(map[string]string) + data, err := Asset("smc.tsv") + parser := csv.NewReader(bytes.NewReader(data)) + parser.Comma = '\t' + var line []string + for { + if line, err = parser.Read(); err == io.EOF { + break + } + if err != nil { + // FIXME log an error here + break + } + // The line is malformed if len(line) != 2, but because the asset is static + // it makes no sense to report the error to downstream users. This must be + // tested at/around compile time. + // FIXME assert all lines in smc.tsv have 2 columns during unit tests + if len(line) == 2 { + rv[line[0]] = line[1] } } return rv diff --git a/devices/temp_darwin_test.go b/devices/temp_darwin_test.go new file mode 100644 index 0000000..6222b57 --- /dev/null +++ b/devices/temp_darwin_test.go @@ -0,0 +1,45 @@ +// +build darwin + +package devices + +import ( + "testing" +) + +func Test_loadIDs(t *testing.T) { + tests := []struct { + key string + want string + }{ + {"TCAD", "CPU 1 Package Alt."}, + {"TC1P", "CPU 2 Proximity"}, + {"TC1H", "CPU 2 Heatsink"}, + {"TC1D", "CPU 2 Package"}, + {"TC1E", "CPU 2"}, + {"TC1F", "CPU 2"}, + {"TCBH", "CPU 2 Heatsink Alt."}, + {"TCBD", "CPU 2 Package Alt."}, + {"TG0P", "GPU Proximity"}, + {"TG1D", "GPU Die"}, + {"TG0H", "GPU Heatsink"}, + {"TG1H", "GPU Heatsink"}, + {"Ts0S", "Memory Proximity"}, + {"TM0P", "Mem Bank A1"}, + {"TM9P", "Mem Bank B2"}, + {"TCXC", "PECI CPU"}, + {"PSTR", "System Total"}, + } + ids := loadIDs() + L := 161 + if len(ids) != L { + t.Errorf("len(loadIDs) = %d, want %d", len(ids), L) + } + for _, tt := range tests { + t.Run("contents", func(t *testing.T) { + got := ids[tt.key] + if got != tt.want { + t.Errorf("ids[%s] = %v, want %v", tt.key, got, tt.want) + } + }) + } +} diff --git a/devices/temp_linux.go b/devices/temp_linux.go index 09e7d3c..6967232 100644 --- a/devices/temp_linux.go +++ b/devices/temp_linux.go @@ -5,37 +5,15 @@ package devices import ( "strings" - psHost "github.com/shirou/gopsutil/host" + "github.com/shirou/gopsutil/host" ) -func init() { - devs() // Populate the sensorMap - RegisterTemp(getTemps) - RegisterDeviceList(Temperatures, devs, defs) -} - -func getTemps(temps map[string]int) map[string]error { - sensors, err := psHost.SensorsTemperatures() - if err != nil { - return map[string]error{"psHost": err} - } - for _, sensor := range sensors { - label := sensorMap[sensor.SensorKey] - if _, ok := temps[label]; ok { - temps[label] = int(sensor.Temperature) - } - } - return nil -} - -// Optimization to avoid string manipulation every update -var sensorMap map[string]string - +// All possible thermometers func devs() []string { if sensorMap == nil { sensorMap = make(map[string]string) } - sensors, err := psHost.SensorsTemperatures() + sensors, err := host.SensorsTemperatures() if err != nil { return []string{} } diff --git a/devices/temp_nix.go b/devices/temp_nix.go new file mode 100644 index 0000000..0015e1d --- /dev/null +++ b/devices/temp_nix.go @@ -0,0 +1,30 @@ +// +build linux darwin + +package devices + +import ( + "github.com/shirou/gopsutil/host" +) + +func init() { + devs() // Populate the sensorMap + RegisterTemp(getTemps) + RegisterDeviceList(Temperatures, devs, defs) +} + +func getTemps(temps map[string]int) map[string]error { + sensors, err := host.SensorsTemperatures() + if err != nil { + return map[string]error{"gopsutil host": err} + } + for _, sensor := range sensors { + label := sensorMap[sensor.SensorKey] + if _, ok := temps[label]; ok { + temps[label] = int(sensor.Temperature) + } + } + return nil +} + +// Optimization to avoid string manipulation every update +var sensorMap map[string]string diff --git a/docs/releasing.md b/docs/releasing.md index 7704097..8ad4498 100644 --- a/docs/releasing.md +++ b/docs/releasing.md @@ -9,9 +9,10 @@ 7. Finish the draft release and publish. 8. Check gotop-builder for a successful everything build; if successful, publish. 10. Wait for the [AUR](https://github.com/xxxserxxx/gotop-linux] project to finish building. - 1. update arch (gotop-linux) and run `aurpublish aur` and `aurpublish aur-bin` + 1. update arch (gotop-linux) and run `aurpublish gotop` and `aurpublish gotop-bin` + 2. Test install `gotop` and `gotop-bin` with running & version check 11. Notify Nix -12. Notify Homebrew +12. ~~Notify Homebrew~~ Automated now. The AUR project still needs secret credentials to aurpublish to the AUR repository, so the final publish step is still currently manual. @@ -11,7 +11,6 @@ require ( github.com/shibukawa/configdir v0.0.0-20170330084843-e180dbdc8da0 github.com/shirou/gopsutil v2.20.3+incompatible github.com/stretchr/testify v1.4.0 - github.com/xxxserxxx/iSMC v1.0.1 github.com/xxxserxxx/opflag v1.0.5 golang.org/x/sys v0.0.0-20200316230553-a7d97aace0b0 howett.net/plist v0.0.0-20200419221736-3b63eb3a43b5 // indirect @@ -28,8 +28,6 @@ github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7/go.mod h1:ZX github.com/nsf/termbox-go v0.0.0-20190121233118-02980233997d/go.mod h1:IuKpRQcYE1Tfu+oAQqaLisqDeXgjyyltCfsaoYN18NQ= github.com/nsf/termbox-go v0.0.0-20200418040025-38ba6e5628f1 h1:lh3PyZvY+B9nFliSGTn5uFuqQQJGuNrD0MLCokv09ag= github.com/nsf/termbox-go v0.0.0-20200418040025-38ba6e5628f1/go.mod h1:IuKpRQcYE1Tfu+oAQqaLisqDeXgjyyltCfsaoYN18NQ= -github.com/panotza/gosmc v0.0.0-20190601191911-810267459a2a h1:P0QSyHOubLI2e6hccBBEjVX0vPWXoXui5QCAVNWdJSk= -github.com/panotza/gosmc v0.0.0-20190601191911-810267459a2a/go.mod h1:u8Q8dpnMAam0MElxP2KjEROzXMk9G8X168RTpAZ9tPc= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/shibukawa/configdir v0.0.0-20170330084843-e180dbdc8da0 h1:Xuk8ma/ibJ1fOy4Ee11vHhUFHQNpHhrBneOCNHVXS5w= @@ -43,8 +41,6 @@ github.com/valyala/fastrand v1.0.0 h1:LUKT9aKer2dVQNUi3waewTbKV+7H17kvWFNKs2Obdk github.com/valyala/fastrand v1.0.0/go.mod h1:HWqCzkrkg6QXT8V2EXWvXCoow7vLwOFN002oeRzjapQ= github.com/valyala/histogram v1.0.1 h1:FzA7n2Tz/wKRMejgu3PV1vw3htAklTjjuoI6z3d4KDg= github.com/valyala/histogram v1.0.1/go.mod h1:lQy0xA4wUz2+IUnf97SivorsJIp8FxsnRd6x25q7Mto= -github.com/xxxserxxx/iSMC v1.0.1 h1:M9Gkwnnkl+evvnugoB5yRYrbUP+cRIVOPM+xrHZc3Hs= -github.com/xxxserxxx/iSMC v1.0.1/go.mod h1:TGgNjU7BF2DZSuxiTft+BdzxzcujFJYqFfMCzcTl/aY= github.com/xxxserxxx/opflag v1.0.5 h1:2H4Qtl1qe+dSkEcGt+fBe2mQ8z14MgkWPqcLaoa6k90= github.com/xxxserxxx/opflag v1.0.5/go.mod h1:GWZtb3/tGGj5W1GE/JTyJAuqgxDxl1+jqDGAGM+P/p4= golang.org/x/arch v0.0.0-20181203225421-5a4828bb7045/go.mod h1:cYlCBUl1MsqxdiKgmc4uh7TxZfWSFLOGSRR090WDxt8= |