File: cmd_get_sensor_reading.go

package info (click to toggle)
golang-github-bougou-go-ipmi 0.7.8-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 1,880 kB
  • sloc: makefile: 38
file content (151 lines) | stat: -rw-r--r-- 4,474 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
package ipmi

import (
	"context"
	"fmt"
)

// 35.14 Get Sensor Reading Command
//
// Retrieve a raw sensor reading (current reading) from ipmb
type GetSensorReadingRequest struct {
	SensorNumber uint8
}

type GetSensorReadingResponse struct {
	// reading byte. Ignore on read if sensor does not return an numeric (analog) reading
	Reading uint8

	EventMessagesDisabled bool

	// see 16.5 System Software use of Sensor Scanning bits & Entity Info
	//
	// System software must ignore any sensor that has the sensor scanning bit disabled - if system software didn't disable the sensor.
	SensorScanningDisabled bool

	ReadingUnavailable bool // Software should use this bit to avoid getting an incorrect status while the first sensor update is in progress.

	// The following fields are optionally, they are only meaningful when reading is valid.

	Above_UNR bool // at or above UNR threshold
	Above_UCR bool // at or above UCR threshold
	Above_UNC bool // at or above UNC threshold
	Below_LNR bool // at or below LNR threshold
	Below_LCR bool // at or below LCR threshold
	Below_LNC bool // at or below LNC threshold

	// see 42.1
	// (Sensor Classes: Discrete)
	// It is possible for a discrete sensor to have more than one state active at a time.
	ActiveStates Mask_DiscreteEvent

	optionalData1 uint8
	optionalData2 uint8
}

func (req *GetSensorReadingRequest) Command() Command {
	return CommandGetSensorReading
}

func (req *GetSensorReadingRequest) Pack() []byte {
	out := make([]byte, 1)
	packUint8(req.SensorNumber, out, 0)
	return out
}

func (res *GetSensorReadingResponse) Unpack(msg []byte) error {
	if len(msg) < 2 {
		return ErrUnpackedDataTooShortWith(len(msg), 2)
	}
	res.Reading, _, _ = unpackUint8(msg, 0)

	b1, _, _ := unpackUint8(msg, 1)
	res.EventMessagesDisabled = !isBit7Set(b1)
	res.SensorScanningDisabled = !isBit6Set(b1)
	res.ReadingUnavailable = isBit5Set(b1)

	if len(msg) >= 3 {
		b2, _, _ := unpackUint8(msg, 2)
		// For threshold-based sensors, Present threshold comparison status
		res.Above_UNR = isBit5Set(b2)
		res.Above_UCR = isBit4Set(b2)
		res.Above_UNC = isBit3Set(b2)
		res.Below_LNR = isBit2Set(b2)
		res.Below_LCR = isBit1Set(b2)
		res.Below_LNC = isBit0Set(b2)
		// For discrete reading sensors
		res.ActiveStates.State_7 = isBit7Set(b2)
		res.ActiveStates.State_6 = isBit6Set(b2)
		res.ActiveStates.State_5 = isBit5Set(b2)
		res.ActiveStates.State_4 = isBit4Set(b2)
		res.ActiveStates.State_3 = isBit3Set(b2)
		res.ActiveStates.State_2 = isBit2Set(b2)
		res.ActiveStates.State_1 = isBit1Set(b2)
		res.ActiveStates.State_0 = isBit0Set(b2)

		res.optionalData1 = b2
	}

	// For discrete reading sensors only. (Optional)
	if len(msg) >= 4 {
		b3, _, _ := unpackUint8(msg, 3)
		// For discrete reading sensors
		res.ActiveStates.State_14 = isBit6Set(b3)
		res.ActiveStates.State_13 = isBit5Set(b3)
		res.ActiveStates.State_12 = isBit4Set(b3)
		res.ActiveStates.State_11 = isBit3Set(b3)
		res.ActiveStates.State_10 = isBit2Set(b3)
		res.ActiveStates.State_9 = isBit1Set(b3)
		res.ActiveStates.State_8 = isBit0Set(b3)

		res.optionalData2 = b3
	}

	return nil
}

func (r *GetSensorReadingResponse) CompletionCodes() map[uint8]string {
	// no command-specific cc
	return map[uint8]string{}
}

func (r *GetSensorReadingResponse) ThresholdStatus() SensorThresholdStatus {
	if r.Above_UCR {
		return SensorThresholdStatus_UCR
	}
	if r.Above_UNC {
		return SensorThresholdStatus_UCR
	}
	if r.Above_UNR {
		return SensorThresholdStatus_UCR
	}
	if r.Below_LCR {
		return SensorThresholdStatus_UCR
	}
	if r.Below_LNC {
		return SensorThresholdStatus_UCR
	}
	if r.Below_LNR {
		return SensorThresholdStatus_UCR
	}
	return SensorThresholdStatus_OK
}

func (res *GetSensorReadingResponse) Format() string {
	return "" +
		fmt.Sprintf("Sensor Reading         : %d\n", res.Reading) +
		fmt.Sprintf("Event Message Disabled : %v\n", res.EventMessagesDisabled) +
		fmt.Sprintf("Scanning Disabled      : %v\n", res.SensorScanningDisabled) +
		fmt.Sprintf("Reading Unavailable    : %v\n", res.ReadingUnavailable) +
		fmt.Sprintf("Threshold Status       : %s\n", res.ThresholdStatus()) +
		fmt.Sprintf("Discrete Events        : %v\n", res.ActiveStates.TrueEvents())
}

func (c *Client) GetSensorReading(ctx context.Context, sensorNumber uint8) (response *GetSensorReadingResponse, err error) {
	request := &GetSensorReadingRequest{
		SensorNumber: sensorNumber,
	}
	response = &GetSensorReadingResponse{}
	err = c.Exchange(ctx, request, response)
	return
}