forked from bougou/go-ipmi
/
types_sensor.go
1177 lines (1028 loc) · 36.9 KB
/
types_sensor.go
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
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
package ipmi
import (
"bytes"
"fmt"
"math"
"github.com/olekukonko/tablewriter"
)
// 42.1
// Sensors are classified according to the type of readings they provide and/or the type of events they generate.
//
// Three sensor classes: threshold, discrete, oem
// (oem is a special case of discrete)
//
// A sensor can return either an analog or discrete readings. Sensor events can be discrete or threshold-based.
// Valid sensorclass string values are:
// "N/A", "threshold", "discrete", "oem"
type SensorClass string
const (
SensorClassNotApplicable SensorClass = "N/A" // 不适用的
SensorClassThreshold SensorClass = "threshold"
// 离散 multiple states possible
// Discrete sensors can contain up to 15 possible states.
// It is possible for a discrete sensor to have more than one state active at a time
SensorClassDiscrete SensorClass = "discrete"
// A digital sensor is not really a unique class, but a term commonly used to refer to
// special case of a discrete sensor that only has two possible states
// SensorClassDigitalDiscrete SensorClass = "digital-discrete"
// Special case of discrete where the meaning of the states (offsets) are OEM defined.
SensorClassOEM SensorClass = "oem"
)
// 41.1 Sensor Type Code
// 42.2 Sensor Type Codes and Data
type SensorType uint8
func (c SensorType) String() string {
s, ok := sensorTypeMap[c]
if ok {
return s
}
return "unkown"
}
const (
SensorTypeReserved SensorType = 0x00
SensorTypeTemperature SensorType = 0x01 // 温度传感器
SensorTypeVoltage SensorType = 0x02 // 电压传感器
SensorTypeCurrent SensorType = 0x03 // 电流传感器
SensorTypeFan SensorType = 0x04 // 风扇传感器
SensorTypePhysicalSecurity SensorType = 0x05 // Chassis Intrusion
SensorTypePlatformSecurity SensorType = 0x06
SensorTypeProcessor SensorType = 0x07
SensorTypePowserSupply SensorType = 0x08
SensorTypePowerUnit SensorType = 0x09
SensorTypeCollingDevice SensorType = 0x0a
SensorTypeOtherUnitsbased SensorType = 0x0b
SensorTypeMemory SensorType = 0x0c
SensorTypeDriveSlot SensorType = 0x0d
SensorTypePostMemoryResize SensorType = 0x0e
SensorTypeSystemFirmwareProgress SensorType = 0x0f
SensorTypeEventLoggingDisabled SensorType = 0x10
SensorTypeWatchdog1 SensorType = 0x11
SensorTypeSystemEvent SensorType = 0x12
SensorTypeCriticalInterrupt SensorType = 0x13
SensorTypeButtonSwitch SensorType = 0x14
SensorTypeModuleBoard SensorType = 0x15
SensorTypeMicrocontrollerCoprocessor SensorType = 0x16
SensorTypeAddinCard SensorType = 0x17
SensorTypeChassis SensorType = 0x18
SensorTypeChipSet SensorType = 0x19
SensorTypeOtherFRU SensorType = 0x1a
SensorTypeCableInterconnect SensorType = 0x1b
SensorTypeTerminator SensorType = 0x1c
SensorTypeSystemBootRestartInitiated SensorType = 0x1d
SensorTypeBootError SensorType = 0x1e
SensorTypeBaseOSBootInstallationStatus SensorType = 0x1f
SensorTypeOSStopShutdown SensorType = 0x20
SensorTypeSlotConnector SensorType = 0x21
SensorTypeSystemACPIPowerState SensorType = 0x22
SensorTypeWatchdog2 SensorType = 0x23
SensorTypePlatformAlert SensorType = 0x24
SensorTypeEntityPresence SensorType = 0x25
SensorTypeMonitorASIC SensorType = 0x26
SensorTypeLAN SensorType = 0x27
SensorTypeManagementSubsystemHealth SensorType = 0x28
SensorTypeBattery SensorType = 0x29
SensorTypeSessionAudit SensorType = 0x2a
SensorTypeVersionChange SensorType = 0x2b
SensorTypeFRUState SensorType = 0x2c
// Reserverd: 0x2D - 0xBF
// OEM Reserved: 0xC0 - 0xFF
)
var sensorTypeMap = map[SensorType]string{
0x00: "Reserved",
0x01: "Temperature",
0x02: "Voltage",
0x03: "Current",
0x04: "Fan",
0x05: "Physical Security",
0x06: "Platform Security",
0x07: "Processor",
0x08: "Power Supply",
0x09: "Power Unit",
0x0a: "Cooling Device",
0x0b: "Other",
0x0c: "Memory",
0x0d: "Drive Slot / Bay",
0x0e: "POST Memory Resize",
0x0f: "System Firmwares",
0x10: "Event Logging Disabled",
0x11: "Watchdog1",
0x12: "System Event",
0x13: "Critical Interrupt",
0x14: "Button",
0x15: "Module / Board",
0x16: "Microcontroller/Coprocessor",
0x17: "Add-in Card",
0x18: "Chassis",
0x19: "Chip Set",
0x1a: "Other FRU",
0x1b: "Cable / Interconnect",
0x1c: "Terminator",
0x1d: "System Boot Initiated",
0x1e: "Boot Error",
0x1f: "OS Boot",
0x20: "OS Critical Stop",
0x21: "Slot / Connector",
0x22: "System ACPI Power State",
0x23: "Watchdog2",
0x24: "Platform Alert",
0x25: "Entity Presence",
0x26: "Monitor ASIC",
0x27: "LAN",
0x28: "Management Subsys Health",
0x29: "Battery",
0x2a: "Session Audit",
0x2b: "Version Change",
0x2c: "FRU State",
}
// 43.17 Sensor Unit Type Codes
type SensorUnitType uint8
const (
SensorUnitType_Unspecified SensorUnitType = 0 // unspecified
SensorUnitType_DegressC SensorUnitType = 1 // degrees C, Celsius, 摄氏度 ℃
SensorUnitType_DegreesF SensorUnitType = 2 // degrees F, Fahrenheit, 华氏度
SensorUnitType_DegreesK SensorUnitType = 3 // degrees K, Kelvins, 开尔文
SensorUnitType_Volts SensorUnitType = 4 // Volts, 伏特(电压单位)
SensorUnitType_Amps SensorUnitType = 5 // Amps, 安培数
SensorUnitType_Watts SensorUnitType = 6 // Watts, 瓦特(功率单位)
SensorUnitType_Joules SensorUnitType = 7 // Joules, 焦耳
SensorUnitType_Coulombs SensorUnitType = 8 // Coulombs, 库伦
SensorUnitType_VA SensorUnitType = 9 // VA, 伏安
SensorUnitType_Nits SensorUnitType = 10 // Nits, 尼特(光度单位)
SensorUnitType_Lumen SensorUnitType = 11 // lumen, 流明(光通量单位)
SensorUnitType_Lux SensorUnitType = 12 // lux, 勒克斯(照明单位)
SensorUnitType_Candela SensorUnitType = 13 // Candela, 坎, 坎德拉(发光强度单位)
SensorUnitType_KPa SensorUnitType = 14 // kPa kilopascal, 千帕, 千帕斯卡
SensorUnitType_PSI SensorUnitType = 15 // PSI
SensorUnitType_Newton SensorUnitType = 16 // Newton, 牛顿(力的单位)
SensorUnitType_CFM SensorUnitType = 17 // CFM, 风量, cubic feet per minute (cu ft/min)
SensorUnitType_RPM SensorUnitType = 18 // RPM, 每分钟转数, Revolutions per minute, is the number of turns in one minute
SensorUnitType_Hz SensorUnitType = 19 // Hz, 赫兹
SensorUnitType_MicroSecond SensorUnitType = 20 // microsecond, 微秒
SensorUnitType_MilliSecond SensorUnitType = 21 // millisecond, 毫秒
SensorUnitType_Second SensorUnitType = 22 // second, 秒
SensorUnitType_Minute SensorUnitType = 23 // minute, 分
SensorUnitType_Hour SensorUnitType = 24 // hour, 时
SensorUnitType_Day SensorUnitType = 25 // day, 日
SensorUnitType_Week SensorUnitType = 26 // week, 周
SensorUnitType_Mil SensorUnitType = 27 // mil, 毫升;密耳(千分之一寸)
SensorUnitType_Inches SensorUnitType = 28 // inches, 英寸(inch的复数)
SensorUnitType_Fleet SensorUnitType = 29 // feet
SensorUnitType_CuIn SensorUnitType = 30 // cu in, 立方英寸(cubic inch)
SensorUnitType_CuFleet SensorUnitType = 31 // cu feet
SensorUnitType_MM SensorUnitType = 32 // mm, 毫米(millimeter)
SensorUnitType_CM SensorUnitType = 33 // cm, 厘米(centimeter)
SensorUnitType_M SensorUnitType = 34 // m, 米
SensorUnitType_CuCM SensorUnitType = 35 // cu cm
SensorUnitType_Cum SensorUnitType = 36 // cum
SensorUnitType_Liters SensorUnitType = 37 // liters, 公升(容量单位)
SensorUnitType_FluidOunce SensorUnitType = 38 // fluid ounce, 液盎司(液体容量单位, 等于 fluidounce)
SensorUnitType_Radians SensorUnitType = 39 // radians, 弧度(radian的复数)
SensorUnitType_vSteradians SensorUnitType = 40 // steradians, 球面度, 立体弧度(立体角国际单位制, 等于 sterad)
SensorUnitType_Revolutions SensorUnitType = 41 // revolutions, 转数(revolution的复数形式)
SensorUnitType_Cycles SensorUnitType = 42 // cycles, 周期, 圈
SensorUnitType_Gravities SensorUnitType = 43 // gravities, 重力
SensorUnitType_Ounce SensorUnitType = 44 // ounce, 盎司
SensorUnitType_Pound SensorUnitType = 45 // pound, 英镑
SensorUnitType_FootPound SensorUnitType = 46 // ft-lb, 英尺-磅(foot pound)
SensorUnitType_OzIn SensorUnitType = 47 // oz-in, 扭力;盎司英寸
SensorUnitType_Gauss SensorUnitType = 48 // gauss, 高斯(磁感应或磁场的单位)
SensorUnitType_Gilberts SensorUnitType = 49 // gilberts, 吉伯(磁通量的单位)
SensorUnitType_Henry SensorUnitType = 50 // henry, 亨利(电感单位)
SensorUnitType_MilliHenry SensorUnitType = 51 // millihenry, 毫亨(利)(电感单位)
SensorUnitType_Farad SensorUnitType = 52 // farad, 法拉(电容单位)
SensorUnitType_MicroFarad SensorUnitType = 53 // microfarad, 微法拉(电容量的实用单位)
SensorUnitType_Ohms SensorUnitType = 54 // ohms, 欧姆(Ohm) :电阻的量度单位, 欧姆值越大, 电阻越大
SensorUnitType_Siemens SensorUnitType = 55 // siemens, 西门子, 电导单位
SensorUnitType_Mole SensorUnitType = 56 // mole, 摩尔 [化学] 克分子(等于mole)
SensorUnitType_Becquerel SensorUnitType = 57 // becquerel, 贝可(放射性活度单位)
SensorUnitType_PPM SensorUnitType = 58 // PPM (parts/million), 百万分率, 百万分之…(parts per million)
SensorUnitType_Reserved SensorUnitType = 59 // reserved
SensorUnitType_Decibels SensorUnitType = 60 // Decibels, 分贝(声音强度单位, decibel的复数)
SensorUnitType_DbA SensorUnitType = 61 // DbA, dBA is often used to specify the loudness of the fan used to cool the microprocessor and associated components. Typical dBA ratings are in the neighborhood of 25 dBA, representing 25 A-weighted decibels above the threshold of hearing. This is approximately the loudness of a person whispering in a quiet room.
SensorUnitType_DbC SensorUnitType = 62 // DbC
SensorUnitType_Gray SensorUnitType = 63 // gray, 核吸收剂量(Gy)
SensorUnitType_Severt SensorUnitType = 64 // sievert, 希沃特(辐射效果单位, 简称希)
SensorUnitType_ColorTempDegK SensorUnitType = 65 // color temp deg K, 色温
SensorUnitType_Bit SensorUnitType = 66 // bit, 比特(二进位制信息单位)
SensorUnitType_Kilobit SensorUnitType = 67 // kilobit, 千比特
SensorUnitType_Megabit SensorUnitType = 68 // megabit, 兆比特
SensorUnitType_Gigabit SensorUnitType = 69 // gigabit, 吉比特
SensorUnitType_Byte SensorUnitType = 70 // byte, 字节
SensorUnitType_Kilobyte SensorUnitType = 71 // kilobyte, 千字节
SensorUnitType_Megabyte SensorUnitType = 72 // megabyte, 兆字节
SensorUnitType_Gigabyte SensorUnitType = 73 // gigabyte, 吉字节
SensorUnitType_Word SensorUnitType = 74 // word (data), 字
SensorUnitType_DWord SensorUnitType = 75 // dword, 双字
SensorUnitType_QWord SensorUnitType = 76 // qword, 四字
SensorUnitType_Line SensorUnitType = 77 // line (re. mem. line)
SensorUnitType_Hit SensorUnitType = 78 // hit, 命中
SensorUnitType_Miss SensorUnitType = 79 // miss, 未击中, 未命中
SensorUnitType_Retry SensorUnitType = 80 // retry, 重试(次数)
SensorUnitType_Reset SensorUnitType = 81 // reset, 重置(次数)
SensorUnitType_Overrun SensorUnitType = 82 // overrun) / overflow 满载, 溢出(次数)
SensorUnitType_Underrun SensorUnitType = 83 // underrun 欠载
SensorUnitType_Collision SensorUnitType = 84 // collision, 冲突
SensorUnitType_Packet SensorUnitType = 85 // packets, 包, 数据包
SensorUnitType_Message SensorUnitType = 86 // messages, 消息
SensorUnitType_Characters SensorUnitType = 87 // characters, 字符
SensorUnitType_Error SensorUnitType = 88 // error, 错误
SensorUnitType_CorrectableError SensorUnitType = 89 // correctable error 可校正错误
SensorUnitType_UncorrectableError SensorUnitType = 90 // uncorrectable error 不可校正错误
SensorUnitType_FatalError SensorUnitType = 91 // fatal error, 致命错误, 不可恢复的错误
SensorUnitType_Grams SensorUnitType = 92 // grams, 克(gram的复数形式)
)
func (u SensorUnitType) String() string {
s, ok := sensorUnitMap[u]
if ok {
return s
}
return ""
}
var sensorUnitMap = map[SensorUnitType]string{
0: "unspecified",
1: "degrees C",
2: "degrees F",
3: "degrees K",
4: "Volts",
5: "Amps",
6: "Watts",
7: "Joules",
8: "Coulombs",
9: "VA",
10: "Nits",
11: "lumen",
12: "lux",
13: "Candela",
14: "kPa",
15: "PSI",
16: "Newton",
17: "CFM",
18: "RPM",
19: "Hz",
20: "microsecond",
21: "millisecond",
22: "second",
23: "minute",
24: "hour",
25: "day",
26: "week",
27: "mil",
28: "inches",
29: "feet",
30: "cu in",
31: "cu feet",
32: "mm",
33: "cm",
34: "m",
35: "cu cm",
36: "cu m",
37: "liters",
38: "fluid ounce",
39: "radians",
40: "steradians",
41: "revolutions",
42: "cycles",
43: "gravities",
44: "ounce",
45: "pound",
46: "ft-lb",
47: "oz-in",
48: "gauss",
49: "gilberts",
50: "henry",
51: "millihenry",
52: "farad",
53: "microfarad",
54: "ohms",
55: "siemens",
56: "mole",
57: "becquerel",
58: "PPM",
59: "reserved",
60: "Decibels",
61: "DbA",
62: "DbC",
63: "gray",
64: "sievert",
65: "color temp deg K",
66: "bit",
67: "kilobit",
68: "megabit",
69: "gigabit",
70: "byte",
71: "kilobyte",
72: "megabyte",
73: "gigabyte",
74: "word",
75: "dword",
76: "qword",
77: "line",
78: "hit",
79: "miss",
80: "retry",
81: "reset",
82: "overflow",
83: "underrun",
84: "collision",
85: "packets",
86: "messages",
87: "characters",
88: "error",
89: "correctable error",
90: "uncorrectable error",
91: "fatal error",
92: "grams",
}
// SensorThresholdType are enums for types of threshold
type SensorThresholdType string
const (
SensorThresholdType_LNC SensorThresholdType = "LowerNonCritical"
SensorThresholdType_LCR SensorThresholdType = "LowerCritical"
SensorThresholdType_LNR SensorThresholdType = "LowerNonRecoverable"
SensorThresholdType_UNC SensorThresholdType = "UpperNonCritical"
SensorThresholdType_UCR SensorThresholdType = "UpperCritical"
SensorThresholdType_UNR SensorThresholdType = "UpperNonRecoverable"
)
func (sensorThresholdType SensorThresholdType) Abbr() string {
m := map[SensorThresholdType]string{
SensorThresholdType_LNC: "lnc",
SensorThresholdType_LCR: "lcr",
SensorThresholdType_LNR: "lnr",
SensorThresholdType_UNC: "unc",
SensorThresholdType_UCR: "ucr",
SensorThresholdType_UNR: "unr",
}
s, ok := m[sensorThresholdType]
if ok {
return s
}
return ""
}
type SensorThresholdTypes []SensorThresholdType
func (types SensorThresholdTypes) Strings() []string {
out := []string{}
for _, v := range types {
out = append(out, v.Abbr())
}
return out
}
// SensorThresholdStatus are enums for threshold status of sensor.
//
// ....UNR status (NonRecoverable)
// -----------------UNR threshold
// ....UCR status (Critical)
// -----------------UCR threshold
// ....UNC status (NonCritical)
// -----------------UNC threshold
// ....OK status (OK)
// -----------------LNC threshold
// ....LNC status (NonCritical)
// -----------------LCR threshold
// ....LCR status (Critical)
// -----------------LNR threshold
// ....LNR status (NonRecoverable)
type SensorThresholdStatus string
const (
SensorThresholdStatus_OK = "ok"
SensorThresholdStatus_LNC = "lnc"
SensorThresholdStatus_LCR = "lcr"
SensorThresholdStatus_LNR = "lnr"
SensorThresholdStatus_UNC = "unc"
SensorThresholdStatus_UCR = "ucr"
SensorThresholdStatus_UNR = "unr"
)
type SensorStatus string
const (
// SensorStatusOK means okay (the sensor is present and operating correctly)
SensorStatusOK = "ok"
// SensorStatusNoSensor means no sensor (corresponding reading will say disabled or Not Readable)
SensorStatusNoSensor = "ns"
// SensorStatusNonCritical means non-critical error (lower or upper)
SensorStatusNonCritical = "nc"
// SensorStatusCritical means critical error (lower or upper)
SensorStatusCritical = "cr"
// SensorStatusNonRecoverable means non-recoverable error (lower or upper)
SensorStatusNonRecoverable = "nr"
)
// SensorThreshold holds all values and attributes of a specified threshold type.
type SensorThreshold struct {
// type of threshold
Type SensorThresholdType
Mask Mask_Threshold
// theshold raw reading value before conversion
Raw uint8
}
// LinearizationFunc is linearization function used in "Sensor Reading Conversion Formula"
// 线性化函数
type LinearizationFunc uint8
const (
LinearizationFunc_Linear LinearizationFunc = 0x00
LinearizationFunc_LN LinearizationFunc = 0x01
LinearizationFunc_LOG10 LinearizationFunc = 0x02
LinearizationFunc_LOG2 LinearizationFunc = 0x03
LinearizationFunc_E LinearizationFunc = 0x04
LinearizationFunc_EXP10 LinearizationFunc = 0x05
LinearizationFunc_EXP2 LinearizationFunc = 0x06
LinearizationFunc_1X LinearizationFunc = 0x07
LinearizationFunc_SQR LinearizationFunc = 0x08
LinearizationFunc_CUBE LinearizationFunc = 0x09
LinearizationFunc_SQRT LinearizationFunc = 0x0a
LinearizationFunc_CUBERT LinearizationFunc = 0x0b
// 70h = non-linear.
// 71h-7Fh = non-linear OEM
LinearizationFunc_NonLinear LinearizationFunc = 0x70
)
func (l LinearizationFunc) IsNonLinear() bool {
if uint8(l) >= 0x70 && uint8(l) <= 0x7f {
return true
}
return false
}
func (l LinearizationFunc) String() string {
m := map[LinearizationFunc]string{
0x00: "linear",
0x01: "ln",
0x02: "log10",
0x03: "log2",
0x04: "e",
0x05: "exp10",
0x06: "exp2",
0x07: "1/x",
0x08: "sqr(x)", // 平方 sqr(3) = 9
0x09: "cube(x)", // 立方 cube(3) = 27
0x0a: "sqrt(x)", // 平方根 sqrt(9) = 3
0x0b: "cubert(x)", // 立方根 cubert(27) = 3
}
s, ok := m[l]
if ok {
return fmt.Sprintf("%s(%d)", s, uint8(l))
}
return fmt.Sprintf("(%d)", uint8(l))
}
// Apply applies linearization func (itself) to the input value and returns the result.
func (l LinearizationFunc) Apply(x float64) float64 {
switch l {
case LinearizationFunc_LN:
return math.Log(float64(x))
case LinearizationFunc_LOG10:
return math.Log10(float64(x))
case LinearizationFunc_LOG2:
return math.Log2(float64(x))
case LinearizationFunc_E:
return math.Pow(math.E, float64(x))
case LinearizationFunc_EXP10:
return math.Pow10(int(x))
case LinearizationFunc_EXP2:
return math.Exp2(float64(x))
case LinearizationFunc_1X:
return math.Pow(float64(x), -1)
case LinearizationFunc_SQR:
return math.Pow(float64(x), 2.0)
case LinearizationFunc_CUBE:
return math.Pow(float64(x), 3.0)
case LinearizationFunc_SQRT:
return math.Sqrt(float64(x))
case LinearizationFunc_CUBERT:
return math.Cbrt(float64(x))
case LinearizationFunc_Linear:
// `linear means y=f(x)=x`, nothing to do
default:
// other values mean sensor is non-linear, also no linearization function is applied. (see 36.2 third paragraph)
}
return x
}
type SensorUnit struct {
AnalogDataFormat SensorAnalogUnitFormat
RateUnit SensorRateUnit
ModifierRelation SensorModifierRelation
Percentage bool // Percentage 0b = no, 1b = yes
BaseUnit SensorUnitType
ModifierUnit SensorUnitType
}
func (unit SensorUnit) String() string {
if !unit.IsAnalog() {
return "discrete"
}
// return unit.BaseUnit.String()
var percentageStr string
if unit.Percentage {
percentageStr = "% "
}
switch unit.ModifierRelation {
case SensorModifierRelation_Div:
return fmt.Sprintf("%s%s/%s", percentageStr, unit.BaseUnit, unit.ModifierUnit)
case SensorModifierRelation_Mul:
return fmt.Sprintf("%s%s*%s", percentageStr, unit.BaseUnit, unit.ModifierUnit)
// SensorModifierRelation_None:
default:
if unit.BaseUnit == SensorUnitType_Unspecified && unit.Percentage {
return "percent"
}
return fmt.Sprintf("%s%s", percentageStr, unit.BaseUnit)
}
}
func (unit SensorUnit) IsAnalog() bool {
return unit.AnalogDataFormat != SensorAnalogUnitFormat_NotAnalog
}
type SensorAnalogUnitFormat uint8
const (
SensorAnalogUnitFormat_Unsigned SensorAnalogUnitFormat = 0 // unsigned
SensorAnalogUnitFormat_1sComplement SensorAnalogUnitFormat = 1 // 1's complement (signed)
SensorAnalogUnitFormat_2sComplement SensorAnalogUnitFormat = 2 // 2's complement (signed)
SensorAnalogUnitFormat_NotAnalog SensorAnalogUnitFormat = 3 // does not return analog (numeric) reading
)
func (format SensorAnalogUnitFormat) String() string {
m := map[SensorAnalogUnitFormat]string{
0: "unsigned",
1: "1s comp",
2: "2s comp",
3: "not analog",
}
s, ok := m[format]
if ok {
return s
}
return "unknown"
}
type SensorRateUnit uint8
const (
SensorRateUnit_None SensorRateUnit = 0
SensorRateUnit_PerMicroSec SensorRateUnit = 1
SensorRateUnit_PerMilliSec SensorRateUnit = 2
SensorRateUnit_PerSec SensorRateUnit = 3
SensorRateUnit_PerMin SensorRateUnit = 4
SensorRateUnit_PerHour SensorRateUnit = 5
SensorRateUnit_PerDay SensorRateUnit = 6
SensorRateUnit_Reserved SensorRateUnit = 7
)
func (unit SensorRateUnit) String() string {
m := map[SensorRateUnit]string{
0: "none",
1: "per µS",
2: "per ms",
3: "per s",
4: "per minute",
5: "per hour",
6: "per day",
7: "reserved",
}
s, ok := m[unit]
if ok {
return s
}
return ""
}
type SensorModifierRelation uint8
const (
SensorModifierRelation_None SensorModifierRelation = 0
SensorModifierRelation_Div SensorModifierRelation = 1 // Basic Unit / Modifier Unit
SensorModifierRelation_Mul SensorModifierRelation = 2 // Basic Unit * Mofifier Unit
)
func (unit SensorModifierRelation) String() string {
m := map[SensorModifierRelation]string{
0: "none",
1: "div",
2: "mul",
3: "reserved",
}
s, ok := m[unit]
if ok {
return s
}
return ""
}
// SensorEventMessageControl indicates whether this sensor generates Event Messages,
// and if so, what type of Event Message control is offered.
type SensorEventMessageControl uint8
const (
// per threshold/discrete-state event enable/disable control (implies
// that entire sensor and global disable are also supported)
SensorEventMessageControl_PerThresholdState SensorEventMessageControl = 0
// entire sensor only (implies that global disable is also supported)
SensorEventMessageControl_EntireSensorOnly SensorEventMessageControl = 1
// global disable only
SensorEventMessageControl_GlobalDisableOnly SensorEventMessageControl = 2
// no events from sensor
SensorEventMessageControl_NoEvents SensorEventMessageControl = 3
)
func (a SensorEventMessageControl) String() string {
switch a {
case 0:
return "Per-threshold"
case 1:
return "Entire Sensor Only"
case 2:
return "Global Disable Only"
case 3:
return "No Events From Sensor"
default:
return ""
}
}
// SensorThresholdAccess represents the access mode for the threshold value of the sensor.
type SensorThresholdAccess uint8
const (
// no thresholds.
SensorThresholdAccess_No SensorThresholdAccess = 0
// thresholds are readable, per Reading Mask, below.
SensorThresholdAccess_Readable SensorThresholdAccess = 1
// thresholds are readable and settable per Reading Mask and Settable Threshold Mask, respectively.
SensorThresholdAccess_ReadableSettable SensorThresholdAccess = 2
// Fixed, unreadable, thresholds. Which thresholds are supported is
// reflected by the Reading Mask. The threshold value fields report
// the values that are hard-coded in the sensor.
SensorThresholdAccess_Fixed SensorThresholdAccess = 3
)
func (a SensorThresholdAccess) String() string {
switch a {
case 0:
return "No"
case 1:
return "Readable"
case 2:
return "ReadableSettable"
case 3:
return "FixedUnreadable"
default:
return ""
}
}
// SensorHysteresisAccess represents the access mode for the hysteresis value of the sensor.
type SensorHysteresisAccess uint8
const (
// No hysteresis, or hysteresis built-in but not specified
SensorHysteresisAccess_No SensorHysteresisAccess = 0
// hysteresis is readable.
SensorHysteresisAccess_Readable SensorHysteresisAccess = 1
// hysteresis is readable and settable.
SensorHysteresisAccess_ReadableSettable SensorHysteresisAccess = 2
// Fixed, unreadable, hysteresis. Hysteresis fields values implemented in the sensor.
SensorHysteresisAccess_Fixed SensorHysteresisAccess = 3
)
func (a SensorHysteresisAccess) String() string {
switch a {
case 0:
return "No"
case 1:
return "Readable"
case 2:
return "ReadableSettable"
case 3:
return "FixedUnreadable"
default:
return ""
}
}
// ReadingFactors is used in "Sensor Reading Conversion Formula"
// Only Full SDR defines reading factors.
// see: 36.3 Sensor Reading Conversion Formula
type ReadingFactors struct {
M int16 // 10 bits used
// in +/- ½ raw counts
Tolerance uint8 // 6 bits used
B int16 // 10 bits used
// Unsigned, 10-bit Basic Sensor Accuracy in 1/100 percent scaled up by unsigned Accuracy exponent.
Accuracy uint16 // 10 bits, unsigned
Accuracy_Exp uint8 // 2 bits, unsigned
// [7:4] - R (result) exponent 4 bits, 2's complement, signed
// [3:0] - B exponent 4 bits, 2's complement, signed
R_Exp int8 // 4 bits, signed, also called K2
B_Exp int8 // 4 bits, signed, also called K1
}
func (f ReadingFactors) String() string {
return fmt.Sprintf("M: (%d), T: (%d), B: (%d), A: (%d), A_Exp: (%d), R_Exp: (%d), B_Exp: (%d)",
f.M, f.Tolerance, f.B, f.Accuracy, f.Accuracy_Exp, f.R_Exp, f.B_Exp)
}
// The raw analog data is unpacked as an unsigned interger.
// But whether it is a positive number (>0) or negative number (<0) is determined
// by the "analog data format" field (SensorUnit.AnalogDataFormat)
func AnalogValue(raw uint8, format SensorAnalogUnitFormat) int32 {
switch format {
case SensorAnalogUnitFormat_NotAnalog:
return int32(raw)
case SensorAnalogUnitFormat_Unsigned:
return int32(raw)
case SensorAnalogUnitFormat_1sComplement:
return int32(onesComplement(uint32(raw), 8))
case SensorAnalogUnitFormat_2sComplement:
return int32(twosComplement(uint32(raw), 8))
}
return int32(raw)
}
// ConvertReading converts raw sensor reading or raw sensor threshold value to real value in the desired units for the sensor.
//
// see: 36.3 Sensor Reading Conversion Formula
//
// INPUT: raw (unsigned)
// -- APPLY: analogDataFormat
// --> GOT: analog (signed)
// -- APPLY: factors/linearization
// --> GOT: converted (float64)
func ConvertReading(raw uint8, analogDataFormat SensorAnalogUnitFormat, factors ReadingFactors, linearizationFunc LinearizationFunc) float64 {
// y = L[(Mx + (B * 10^B_Exp) ) * 10^R_Exp ] units
analog := AnalogValue(raw, analogDataFormat)
x := float64(analog)
M := float64(factors.M)
B := float64(factors.B)
Bexp := math.Pow(10, float64(factors.B_Exp))
Rexp := math.Pow(10, float64(factors.R_Exp))
y := (M*x + B*Bexp) * Rexp
return linearizationFunc.Apply(y)
}
// ConvertSensorHysteresis converts raw sensor hysterresis value to real value in the desired units for the sensor.
//
// see: 36.3 Sensor Reading Conversion Formula
func ConvertSensorHysteresis(raw uint8, analogDataFormat SensorAnalogUnitFormat, factors ReadingFactors, linearizationFunc LinearizationFunc) float64 {
// y = L[(Mx + (B * 10^B_Exp) ) * 10^R_Exp ] units
analog := AnalogValue(raw, analogDataFormat)
x := float64(analog)
M := float64(factors.M)
B := float64(factors.B)
Bexp := math.Pow(10, float64(factors.B_Exp))
Rexp := math.Pow(10, float64(factors.R_Exp))
y := (M*x + B*Bexp) * Rexp
return linearizationFunc.Apply(y)
}
// ConvertSensorTolerance converts raw sensor tolerance value to real value in the desired units for the sensor.
//
// see: 36.4.1 Tolerance
func ConvertSensorTolerance(raw uint8, analogDataFormat SensorAnalogUnitFormat, factors ReadingFactors, linearizationFunc LinearizationFunc) float64 {
// y = L[Mx/2 * 10^R_Exp ] units.
analog := AnalogValue(raw, analogDataFormat)
x := float64(analog)
M := float64(factors.M)
Rexp := math.Pow(10, float64(factors.R_Exp))
y := (M * x / 2) * Rexp
return linearizationFunc.Apply(y)
}
// Sensor holds all attribute of a sensor.
type Sensor struct {
SDRRecordType SDRRecordType
Number uint8
Name string
SensorType SensorType
EventReadingType EventReadingType
SensorUnit SensorUnit
SensorInitialization SensorInitialization
SensorCapabilitites SensorCapabilitites
scanningDisabled bool // update by GetSensorReading
readingUnavailable bool // update by GetSensorReading
HasAnalogReading bool
// Raw reading value before conversion
Raw uint8
// reading value after conversion
Value float64
Threshold struct {
Mask Mask_Thresholds
// Threshold Status, udpate by GetSensorReadingResponse.ThresholdStatus()
ThresholdStatus SensorThresholdStatus
// Only Full SDR
LinearizationFunc LinearizationFunc
ReadingFactors
LNC_Raw uint8
LCR_Raw uint8
LNR_Raw uint8
UNC_Raw uint8
UCR_Raw uint8
UNR_Raw uint8
LNC float64
LCR float64
LNR float64
UNC float64
UCR float64
UNR float64
PositiveHysteresisRaw uint8
NegativeHysteresisRaw uint8
PositiveHysteresis float64
NegativeHysteresis float64
}
Discrete struct {
Mask Mask_Discrete
ActiveStates Mask_DiscreteEvent
// filled by GetSensorReadingResponse
optionalData1 uint8
optionalData2 uint8
}
OccuredEvents []SensorEvent
}
func (s *Sensor) String() string {
return fmt.Sprintf(
fmt.Sprintf("Sensor ID : %s (%#02x)\n", s.Name, s.Number) +
fmt.Sprintf(" Sensor Type (%s) : %s (%#02x)\n", string(s.EventReadingType.SensorClass()), s.SensorType.String(), uint8(s.SensorType)) +
fmt.Sprintf(" Sensor Number : %#02x\n", s.Number) +
fmt.Sprintf(" Sensor Name : %s\n", s.Name) +
fmt.Sprintf(" Sensor Reading (raw) : %d\n", s.Raw) +
fmt.Sprintf(" Sensor Value : %.3f %s\n", s.Value, s.SensorUnit) +
fmt.Sprintf(" Sensor Status : %s\n", s.Status()),
)
}
// FormatSensors return a string of table printed for sensors
func FormatSensors(extended bool, sensors ...*Sensor) string {
var buf = new(bytes.Buffer)
table := tablewriter.NewWriter(buf)
table.SetAutoWrapText(false)
headers := []string{
"SDRType",
"SensorNumber",
"SensorName",
"SensorType",
"Reading",
"Unit",
"Status",
"LNR",
"LCR",
"LNC",
"UNC",
"UCR",
"UNR",
}
if extended {
headers = append(headers, []string{
"EventReadingType",
"AnalogDataFormat",
"ReadV",
"ScanD",
"ReadU",
"HasAR",
"DiscreteEvents",
}...)
}
table.SetHeader(headers)
table.SetFooter(headers)
for _, sensor := range sensors {
content := []string{
sensor.SDRRecordType.String(),
fmt.Sprintf("%#02x", sensor.Number),
sensor.Name,
fmt.Sprintf("%s (%#02x)", sensor.SensorType.String(), uint8(sensor.SensorType)),
sensor.ReadingStr(),
sensor.SensorUnit.String(),
sensor.Status(),
sensor.ThresholdStr(SensorThresholdType_LNR),
sensor.ThresholdStr(SensorThresholdType_LCR),
sensor.ThresholdStr(SensorThresholdType_LNC),
sensor.ThresholdStr(SensorThresholdType_UNC),
sensor.ThresholdStr(SensorThresholdType_UCR),
sensor.ThresholdStr(SensorThresholdType_UNR),
}
if extended {
content = append(content, []string{
fmt.Sprintf("%s (%#02x)", sensor.EventReadingType.String(), uint8(sensor.EventReadingType)),
sensor.SensorUnit.AnalogDataFormat.String(),
fmt.Sprintf("%v", sensor.IsReadingValid()),
fmt.Sprintf("%v", sensor.scanningDisabled),
fmt.Sprintf("%v", sensor.readingUnavailable),
fmt.Sprintf("%v", sensor.HasAnalogReading),
}...)
if sensor.IsThreshold() {
content = append(content, "N/A")
} else {
content = append(content, fmt.Sprintf("%v", sensor.Discrete.ActiveStates.TrueEvents()))