master
go 119 lines 2.52 KB
Raw
1 // SPDX-License-Identifier: GPL-3.0-or-later
2
3 package smartctl
4
5 import (
6 "strings"
7
8 "github.com/tidwall/gjson"
9 )
10
11 func newSmartDevice(deviceData *gjson.Result) *smartDevice {
12 return &smartDevice{
13 data: deviceData,
14 }
15 }
16
17 type smartDevice struct {
18 data *gjson.Result
19 }
20
21 func (d *smartDevice) deviceName() string {
22 v := d.data.Get("device.name").String()
23 return strings.TrimPrefix(v, "/dev/")
24 }
25
26 func (d *smartDevice) deviceType() string {
27 return d.data.Get("device.type").String()
28 }
29
30 func (d *smartDevice) serialNumber() string {
31 return d.data.Get("serial_number").String()
32 }
33
34 func (d *smartDevice) modelName() string {
35 for _, s := range []string{"model_name", "scsi_model_name"} {
36 if v := d.data.Get(s); v.Exists() {
37 return v.String()
38 }
39 }
40 return "unknown"
41 }
42
43 func (d *smartDevice) powerOnTime() (int64, bool) {
44 h := d.data.Get("power_on_time.hours")
45 if !h.Exists() {
46 return 0, false
47 }
48 m := d.data.Get("power_on_time.minutes")
49 return h.Int()*60*60 + m.Int()*60, true
50 }
51
52 func (d *smartDevice) temperature() (int64, bool) {
53 v := d.data.Get("temperature.current")
54 return v.Int(), v.Exists()
55 }
56
57 func (d *smartDevice) powerCycleCount() (int64, bool) {
58 for _, s := range []string{"power_cycle_count", "scsi_start_stop_cycle_counter.accumulated_start_stop_cycles"} {
59 if v := d.data.Get(s); v.Exists() {
60 return v.Int(), true
61 }
62 }
63 return 0, false
64 }
65
66 func (d *smartDevice) smartStatusPassed() (bool, bool) {
67 v := d.data.Get("smart_status.passed")
68 return v.Bool(), v.Exists()
69 }
70
71 func (d *smartDevice) ataSmartErrorLogCount() (int64, bool) {
72 v := d.data.Get("ata_smart_error_log.summary.count")
73 return v.Int(), v.Exists()
74 }
75
76 func (d *smartDevice) ataSmartAttributeTable() ([]*smartAttribute, bool) {
77 table := d.data.Get("ata_smart_attributes.table")
78 if !table.Exists() || !table.IsArray() {
79 return nil, false
80 }
81
82 var attrs []*smartAttribute
83
84 for _, data := range table.Array() {
85 attrs = append(attrs, newSmartDeviceAttribute(data))
86 }
87
88 return attrs, true
89 }
90
91 func newSmartDeviceAttribute(attrData gjson.Result) *smartAttribute {
92 return &smartAttribute{
93 data: attrData,
94 }
95 }
96
97 type smartAttribute struct {
98 data gjson.Result
99 }
100
101 func (a *smartAttribute) id() string {
102 return a.data.Get("id").String()
103 }
104
105 func (a *smartAttribute) name() string {
106 return a.data.Get("name").String()
107 }
108
109 func (a *smartAttribute) value() string {
110 return a.data.Get("value").String()
111 }
112
113 func (a *smartAttribute) rawValue() string {
114 return a.data.Get("raw.value").String()
115 }
116
117 func (a *smartAttribute) rawString() string {
118 return a.data.Get("raw.string").String()
119 }