break up client into multiple files
							parent
							
								
									6dfee468e1
								
							
						
					
					
						commit
						0ed88f9c62
					
				@ -0,0 +1,192 @@
 | 
				
			|||||||
 | 
					package client
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// HardwareType type
 | 
				
			||||||
 | 
					// https://github.com/openhardwaremonitor/openhardwaremonitor/blob/e199e0ccc69b4da92495266ebc0faf7daad97608/Hardware/IHardware.cs
 | 
				
			||||||
 | 
					type HardwareType int
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						// UnknownHardware type
 | 
				
			||||||
 | 
						UnknownHardware HardwareType = iota
 | 
				
			||||||
 | 
						// Mainboard type
 | 
				
			||||||
 | 
						Mainboard
 | 
				
			||||||
 | 
						// SuperIO type
 | 
				
			||||||
 | 
						SuperIO
 | 
				
			||||||
 | 
						// CPU type
 | 
				
			||||||
 | 
						CPU
 | 
				
			||||||
 | 
						// RAM type
 | 
				
			||||||
 | 
						RAM
 | 
				
			||||||
 | 
						// GpuNvidia type
 | 
				
			||||||
 | 
						GpuNvidia
 | 
				
			||||||
 | 
						// GpuAti type
 | 
				
			||||||
 | 
						GpuAti
 | 
				
			||||||
 | 
						// TBalancer type
 | 
				
			||||||
 | 
						TBalancer
 | 
				
			||||||
 | 
						// Heatmaster type
 | 
				
			||||||
 | 
						Heatmaster
 | 
				
			||||||
 | 
						// HDD type
 | 
				
			||||||
 | 
						HDD
 | 
				
			||||||
 | 
						// Controller type for TBalancer or Heatmaster
 | 
				
			||||||
 | 
						Controller
 | 
				
			||||||
 | 
						// Computer type for host
 | 
				
			||||||
 | 
						Computer
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Hardware value
 | 
				
			||||||
 | 
					type Hardware struct {
 | 
				
			||||||
 | 
						Type      HardwareType
 | 
				
			||||||
 | 
						Value     string
 | 
				
			||||||
 | 
						TypeIndex int
 | 
				
			||||||
 | 
						TypeCount int
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Sensor for unit
 | 
				
			||||||
 | 
					// https://github.com/openhardwaremonitor/openhardwaremonitor/blob/e199e0ccc69b4da92495266ebc0faf7daad97608/Hardware/ISensor.cs
 | 
				
			||||||
 | 
					type Sensor int
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						// UnknownSensor in V
 | 
				
			||||||
 | 
						UnknownSensor Sensor = iota
 | 
				
			||||||
 | 
						// Voltage in V
 | 
				
			||||||
 | 
						Voltage
 | 
				
			||||||
 | 
						// Clock in MHz
 | 
				
			||||||
 | 
						Clock
 | 
				
			||||||
 | 
						// Temperature in °C
 | 
				
			||||||
 | 
						Temperature
 | 
				
			||||||
 | 
						// Load in %
 | 
				
			||||||
 | 
						Load
 | 
				
			||||||
 | 
						// Fan in RPM
 | 
				
			||||||
 | 
						Fan
 | 
				
			||||||
 | 
						// Flow in L/h
 | 
				
			||||||
 | 
						Flow
 | 
				
			||||||
 | 
						// Control in %
 | 
				
			||||||
 | 
						Control
 | 
				
			||||||
 | 
						// Level in %
 | 
				
			||||||
 | 
						Level
 | 
				
			||||||
 | 
						// Factor in 1
 | 
				
			||||||
 | 
						Factor
 | 
				
			||||||
 | 
						// Power in W
 | 
				
			||||||
 | 
						Power
 | 
				
			||||||
 | 
						// Data in GB = 2^30 Bytes
 | 
				
			||||||
 | 
						Data
 | 
				
			||||||
 | 
						// SmallData in MB = 2^20 Bytes
 | 
				
			||||||
 | 
						SmallData
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var hardwareToMetric = map[HardwareType]string{
 | 
				
			||||||
 | 
						UnknownHardware: "unknown",
 | 
				
			||||||
 | 
						Mainboard:       "mainboard",
 | 
				
			||||||
 | 
						SuperIO:         "superio",
 | 
				
			||||||
 | 
						CPU:             "cpu",
 | 
				
			||||||
 | 
						RAM:             "ram",
 | 
				
			||||||
 | 
						GpuNvidia:       "gpu",
 | 
				
			||||||
 | 
						GpuAti:          "gpu",
 | 
				
			||||||
 | 
						TBalancer:       "tbalancer",
 | 
				
			||||||
 | 
						Heatmaster:      "heatmaster",
 | 
				
			||||||
 | 
						HDD:             "hdd",
 | 
				
			||||||
 | 
						Controller:      "controller",
 | 
				
			||||||
 | 
						Computer:        "host",
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var sensorToMetric = map[Sensor]string{
 | 
				
			||||||
 | 
						UnknownSensor: "unknown",
 | 
				
			||||||
 | 
						Voltage:       "voltage",
 | 
				
			||||||
 | 
						Clock:         "mhz",
 | 
				
			||||||
 | 
						Temperature:   "temp",
 | 
				
			||||||
 | 
						Load:          "load",
 | 
				
			||||||
 | 
						Fan:           "rpm",
 | 
				
			||||||
 | 
						Flow:          "flow",
 | 
				
			||||||
 | 
						Control:       "control",
 | 
				
			||||||
 | 
						Level:         "level",
 | 
				
			||||||
 | 
						Factor:        "factor",
 | 
				
			||||||
 | 
						Power:         "power",
 | 
				
			||||||
 | 
						Data:          "gb",
 | 
				
			||||||
 | 
						SmallData:     "mb",
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var imageToHardware = map[string]HardwareType{
 | 
				
			||||||
 | 
						"ati.png": GpuAti,
 | 
				
			||||||
 | 
						// "bigng.png":     Heatmaster,
 | 
				
			||||||
 | 
						// "bigng.png":     TBalancer,
 | 
				
			||||||
 | 
						"bigng.png":     Controller,
 | 
				
			||||||
 | 
						"chip.png":      SuperIO,
 | 
				
			||||||
 | 
						"cpu.png":       CPU,
 | 
				
			||||||
 | 
						"hdd.png":       HDD,
 | 
				
			||||||
 | 
						"mainboard.png": Mainboard,
 | 
				
			||||||
 | 
						"nvidia.png":    GpuNvidia,
 | 
				
			||||||
 | 
						"ram.png":       RAM,
 | 
				
			||||||
 | 
						"computer.png":  Computer,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var sensorToType = map[string]Sensor{
 | 
				
			||||||
 | 
						"Clocks":       Clock,
 | 
				
			||||||
 | 
						"Controls":     Control,
 | 
				
			||||||
 | 
						"Data":         Data,
 | 
				
			||||||
 | 
						"Factors":      Factor,
 | 
				
			||||||
 | 
						"Fans":         Fan,
 | 
				
			||||||
 | 
						"Flows":        Flow,
 | 
				
			||||||
 | 
						"Levels":       Level,
 | 
				
			||||||
 | 
						"Load":         Load,
 | 
				
			||||||
 | 
						"Powers":       Power,
 | 
				
			||||||
 | 
						"Temperatures": Temperature,
 | 
				
			||||||
 | 
						"Voltages":     Voltage,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (s Sensor) String() string {
 | 
				
			||||||
 | 
						switch s {
 | 
				
			||||||
 | 
						case Clock:
 | 
				
			||||||
 | 
							return "Clock"
 | 
				
			||||||
 | 
						case Control:
 | 
				
			||||||
 | 
							return "Control"
 | 
				
			||||||
 | 
						case Data:
 | 
				
			||||||
 | 
							return "Data"
 | 
				
			||||||
 | 
						case Factor:
 | 
				
			||||||
 | 
							return "Factor"
 | 
				
			||||||
 | 
						case Fan:
 | 
				
			||||||
 | 
							return "Fan"
 | 
				
			||||||
 | 
						case Flow:
 | 
				
			||||||
 | 
							return "Flow"
 | 
				
			||||||
 | 
						case Level:
 | 
				
			||||||
 | 
							return "Level"
 | 
				
			||||||
 | 
						case Load:
 | 
				
			||||||
 | 
							return "Load"
 | 
				
			||||||
 | 
						case Power:
 | 
				
			||||||
 | 
							return "Power"
 | 
				
			||||||
 | 
						case SmallData:
 | 
				
			||||||
 | 
							return "SmallData"
 | 
				
			||||||
 | 
						case Temperature:
 | 
				
			||||||
 | 
							return "Temperature"
 | 
				
			||||||
 | 
						case Voltage:
 | 
				
			||||||
 | 
							return "Voltage"
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return "Unknown"
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (h HardwareType) String() string {
 | 
				
			||||||
 | 
						switch h {
 | 
				
			||||||
 | 
						case UnknownHardware:
 | 
				
			||||||
 | 
							return "Unknown"
 | 
				
			||||||
 | 
						case Mainboard:
 | 
				
			||||||
 | 
							return "Mainboard"
 | 
				
			||||||
 | 
						case SuperIO:
 | 
				
			||||||
 | 
							return "SuperIO"
 | 
				
			||||||
 | 
						case CPU:
 | 
				
			||||||
 | 
							return "CPU"
 | 
				
			||||||
 | 
						case RAM:
 | 
				
			||||||
 | 
							return "RAM"
 | 
				
			||||||
 | 
						case GpuNvidia:
 | 
				
			||||||
 | 
							return "GpuNvidia"
 | 
				
			||||||
 | 
						case GpuAti:
 | 
				
			||||||
 | 
							return "GpuAti"
 | 
				
			||||||
 | 
						case TBalancer:
 | 
				
			||||||
 | 
							return "TBalancer"
 | 
				
			||||||
 | 
						case Heatmaster:
 | 
				
			||||||
 | 
							return "Heatmaster"
 | 
				
			||||||
 | 
						case HDD:
 | 
				
			||||||
 | 
							return "HDD"
 | 
				
			||||||
 | 
						case Controller:
 | 
				
			||||||
 | 
							return "Controller"
 | 
				
			||||||
 | 
						case Computer:
 | 
				
			||||||
 | 
							return "Computer"
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return "Unknown"
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -0,0 +1,155 @@
 | 
				
			|||||||
 | 
					package client
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"fmt"
 | 
				
			||||||
 | 
						"path"
 | 
				
			||||||
 | 
						"strings"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Node from data
 | 
				
			||||||
 | 
					type Node struct {
 | 
				
			||||||
 | 
						ID       int `json:"id"`
 | 
				
			||||||
 | 
						ImageURL string
 | 
				
			||||||
 | 
						Max      string
 | 
				
			||||||
 | 
						Min      string
 | 
				
			||||||
 | 
						Text     string
 | 
				
			||||||
 | 
						Value    string
 | 
				
			||||||
 | 
						Children []Node
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Visitor callback function
 | 
				
			||||||
 | 
					type Visitor func(v Value) error
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// IsValue true if node has children
 | 
				
			||||||
 | 
					func (n *Node) IsValue() bool {
 | 
				
			||||||
 | 
						if n.Children == nil {
 | 
				
			||||||
 | 
							return false
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return len(n.Children) == 0
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// IsRoot returns true if json is a root node
 | 
				
			||||||
 | 
					func (n *Node) IsRoot() bool {
 | 
				
			||||||
 | 
						return n.ID == 0
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// IsSensor returns true if json node is for a sensor type
 | 
				
			||||||
 | 
					func (n *Node) IsSensor() bool {
 | 
				
			||||||
 | 
						if n.ImageURL == "" || n.Text == "" {
 | 
				
			||||||
 | 
							return false
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						_, ok := sensorToType[n.Text]
 | 
				
			||||||
 | 
						return ok
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// SensorType returns type of sensor
 | 
				
			||||||
 | 
					func (n *Node) SensorType() Sensor {
 | 
				
			||||||
 | 
						st, _ := sensorToType[n.Text]
 | 
				
			||||||
 | 
						// Figure out if data is in GB (Data) or MB (SmallData)
 | 
				
			||||||
 | 
						if st == Data {
 | 
				
			||||||
 | 
							if len(n.Children) > 0 {
 | 
				
			||||||
 | 
								val := n.Children[0]
 | 
				
			||||||
 | 
								if strings.HasSuffix(val.Value, "MB") {
 | 
				
			||||||
 | 
									st = SmallData
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return st
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// IsHardware returns true if json node is for hardware
 | 
				
			||||||
 | 
					func (n *Node) IsHardware() bool {
 | 
				
			||||||
 | 
						if n.ImageURL == "" || n.Text == "" {
 | 
				
			||||||
 | 
							return false
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						_, ok := imageToHardware[path.Base(n.ImageURL)]
 | 
				
			||||||
 | 
						return ok
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// HardwareType returns HardwareType of node
 | 
				
			||||||
 | 
					func (n *Node) HardwareType() HardwareType {
 | 
				
			||||||
 | 
						ht, _ := imageToHardware[path.Base(n.ImageURL)]
 | 
				
			||||||
 | 
						return ht
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Walk from json root
 | 
				
			||||||
 | 
					func (n *Node) Walk(fn Visitor) error {
 | 
				
			||||||
 | 
						return n.walk(fn, Value{Hardware: []Hardware{}}, 0, 0)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (n *Node) childDeviceTotals() map[HardwareType]int {
 | 
				
			||||||
 | 
						totals := map[HardwareType]int{}
 | 
				
			||||||
 | 
						for _, child := range n.Children {
 | 
				
			||||||
 | 
							totals[child.HardwareType()]++
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return totals
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (n *Node) walk(fn Visitor, ctx Value, hwIndex, hwTotal int) error {
 | 
				
			||||||
 | 
						if n.IsValue() {
 | 
				
			||||||
 | 
							ctx.Label = n.Text
 | 
				
			||||||
 | 
							ctx.Value = n.Value
 | 
				
			||||||
 | 
							return fn(ctx)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if n.IsSensor() {
 | 
				
			||||||
 | 
							ctx.Unit = n.SensorType()
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if n.IsHardware() {
 | 
				
			||||||
 | 
							ctx.Hardware = append(ctx.Hardware, Hardware{
 | 
				
			||||||
 | 
								Type:      n.HardwareType(),
 | 
				
			||||||
 | 
								Value:     n.Text,
 | 
				
			||||||
 | 
								TypeIndex: hwIndex,
 | 
				
			||||||
 | 
								TypeCount: hwTotal,
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						totals := n.childDeviceTotals()
 | 
				
			||||||
 | 
						deviceIndex := map[HardwareType]int{}
 | 
				
			||||||
 | 
						for _, child := range n.Children {
 | 
				
			||||||
 | 
							deviceType := child.HardwareType()
 | 
				
			||||||
 | 
							index := deviceIndex[deviceType]
 | 
				
			||||||
 | 
							if err := child.walk(fn, ctx, index, totals[deviceType]); err != nil {
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							deviceIndex[deviceType]++
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Values from json root
 | 
				
			||||||
 | 
					func (n *Node) Values() ([]Value, error) {
 | 
				
			||||||
 | 
						ret := []Value{}
 | 
				
			||||||
 | 
						err := n.Walk(func(val Value) error {
 | 
				
			||||||
 | 
							ret = append(ret, val)
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return ret, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Stringify tree
 | 
				
			||||||
 | 
					func (n *Node) Stringify() string {
 | 
				
			||||||
 | 
						return n.stringify(0)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (n *Node) stringify(indent int) string {
 | 
				
			||||||
 | 
						prefix := ""
 | 
				
			||||||
 | 
						for i := 0; i < indent; i++ {
 | 
				
			||||||
 | 
							prefix += "  "
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ret := prefix + n.Text
 | 
				
			||||||
 | 
						if n.Value != "" {
 | 
				
			||||||
 | 
							ret += ": " + n.Value
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if n.Max != "" && n.Min != "" && n.Max != "-" && n.Min != "-" {
 | 
				
			||||||
 | 
							ret += fmt.Sprintf(" (%s - %s)", n.Min, n.Max)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						ret += "\n"
 | 
				
			||||||
 | 
						for _, child := range n.Children {
 | 
				
			||||||
 | 
							ret += child.stringify(indent + 1)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return ret
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -0,0 +1,57 @@
 | 
				
			|||||||
 | 
					package client
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"fmt"
 | 
				
			||||||
 | 
						"strconv"
 | 
				
			||||||
 | 
						"strings"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"github.com/gosimple/slug"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Value from ohwm
 | 
				
			||||||
 | 
					type Value struct {
 | 
				
			||||||
 | 
						Hardware []Hardware
 | 
				
			||||||
 | 
						Unit     Sensor
 | 
				
			||||||
 | 
						Label    string
 | 
				
			||||||
 | 
						Value    string
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Float64 gets value as float64
 | 
				
			||||||
 | 
					func (v *Value) Float64() float64 {
 | 
				
			||||||
 | 
						val := strings.Split(v.Value, " ")
 | 
				
			||||||
 | 
						if len(val) == 0 {
 | 
				
			||||||
 | 
							return 0
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						ret, err := strconv.ParseFloat(val[0], 64)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return 0
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return ret
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// MetricName returns value as a metric name
 | 
				
			||||||
 | 
					func (v *Value) MetricName() string {
 | 
				
			||||||
 | 
						segments := []string{"ohwm"}
 | 
				
			||||||
 | 
						for _, hw := range v.Hardware {
 | 
				
			||||||
 | 
							metricname, ok := hardwareToMetric[hw.Type]
 | 
				
			||||||
 | 
							if !ok {
 | 
				
			||||||
 | 
								metricname = hardwareToMetric[UnknownHardware]
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							segments = append(segments, metricname)
 | 
				
			||||||
 | 
							if hw.TypeCount > 1 {
 | 
				
			||||||
 | 
								segments = append(segments, fmt.Sprintf("%d", hw.TypeIndex))
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						sensorname, ok := sensorToMetric[v.Unit]
 | 
				
			||||||
 | 
						if !ok {
 | 
				
			||||||
 | 
							sensorname = sensorToMetric[UnknownSensor]
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						segments = append(segments, sensorname)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						sluglabel := slug.Make(v.Label)
 | 
				
			||||||
 | 
						segments = append(segments, sluglabel)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ret := strings.Join(segments, "_")
 | 
				
			||||||
 | 
						return strings.ReplaceAll(ret, "-", "_")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
					Loading…
					
					
				
		Reference in New Issue