@@ -31,22 +31,24 @@ const progressBarMultiplier = 2
31
31
32
32
type (
33
33
OtaStatusResponse struct {
34
- FirmwareSize * int64 `json:"firmware_size,omitempty"`
35
- Ota Ota `json:"ota"`
36
- States []State `json:"states,omitempty"`
34
+ Ota Ota `json:"ota"`
35
+ States []State `json:"states,omitempty"`
37
36
}
38
37
39
38
OtaStatusList struct {
40
39
Ota []Ota `json:"ota"`
41
40
}
42
41
43
42
Ota struct {
44
- ID string `json:"id,omitempty" yaml:"id,omitempty"`
45
- DeviceID string `json:"device_id,omitempty" yaml:"device_id,omitempty"`
46
- Status string `json:"status" yaml:"status"`
47
- StartedAt string `json:"started_at" yaml:"started_at"`
48
- EndedAt string `json:"ended_at,omitempty" yaml:"ended_at,omitempty"`
49
- ErrorReason string `json:"error_reason,omitempty" yaml:"error_reason,omitempty"`
43
+ ID string `json:"id,omitempty" yaml:"id,omitempty"`
44
+ DeviceID string `json:"device_id,omitempty" yaml:"device_id,omitempty"`
45
+ Status string `json:"status" yaml:"status"`
46
+ StartedAt string `json:"started_at" yaml:"started_at"`
47
+ EndedAt string `json:"ended_at,omitempty" yaml:"ended_at,omitempty"`
48
+ ErrorReason string `json:"error_reason,omitempty" yaml:"error_reason,omitempty"`
49
+ FirmwareSize int64 `json:"firmware_size,omitempty"`
50
+ MaxRetries int64 `json:"max_retries,omitempty"`
51
+ RetryAttempt int64 `json:"retry_attempt,omitempty"`
50
52
}
51
53
52
54
State struct {
57
59
}
58
60
59
61
OtaStatusDetail struct {
60
- FirmwareSize * int64 `json:"firmware_size,omitempty"`
62
+ FirmwareSize int64 `json:"firmware_size,omitempty"`
63
+ MaxRetries int64 `json:"max_retries,omitempty"`
64
+ RetryAttempt int64 `json:"retry_attempt,omitempty"`
61
65
Ota Ota `json:"ota"`
62
66
Details []State `json:"details,omitempty"`
63
67
}
@@ -81,7 +85,7 @@ func (r OtaStatusList) String() string {
81
85
}
82
86
83
87
if hasErrorReason {
84
- t .SetHeader ("Device ID" , "Ota ID" , "Status" , "Started At" , "Ended At" , "Error Reason" )
88
+ t .SetHeader ("Device ID" , "Ota ID" , "Status" , "Started At" , "Ended At" , "Error Reason" , "Retry Attempt" )
85
89
} else {
86
90
t .SetHeader ("Device ID" , "Ota ID" , "Status" , "Started At" , "Ended At" )
87
91
}
@@ -91,6 +95,7 @@ func (r OtaStatusList) String() string {
91
95
line := []any {r .DeviceID , r .ID , r .MapStatus (), formatHumanReadableTs (r .StartedAt ), formatHumanReadableTs (r .EndedAt )}
92
96
if hasErrorReason {
93
97
line = append (line , r .ErrorReason )
98
+ line = append (line , strconv .FormatInt (r .RetryAttempt , 10 ))
94
99
}
95
100
t .AddRow (line ... )
96
101
}
@@ -114,7 +119,7 @@ func (r Ota) String() string {
114
119
hasErrorReason := r .ErrorReason != ""
115
120
116
121
if hasErrorReason {
117
- t .SetHeader ("Device ID" , "Ota ID" , "Status" , "Started At" , "Ended At" , "Error Reason" )
122
+ t .SetHeader ("Device ID" , "Ota ID" , "Status" , "Started At" , "Ended At" , "Error Reason" , "Retry Attempt" )
118
123
} else {
119
124
t .SetHeader ("Device ID" , "Ota ID" , "Status" , "Started At" , "Ended At" )
120
125
}
@@ -123,6 +128,7 @@ func (r Ota) String() string {
123
128
line := []any {r .DeviceID , r .ID , r .MapStatus (), formatHumanReadableTs (r .StartedAt ), formatHumanReadableTs (r .EndedAt )}
124
129
if hasErrorReason {
125
130
line = append (line , r .ErrorReason )
131
+ line = append (line , strconv .FormatInt (r .RetryAttempt , 10 ))
126
132
}
127
133
t .AddRow (line ... )
128
134
@@ -138,18 +144,21 @@ func (r OtaStatusDetail) String() string {
138
144
return "No OTA found"
139
145
}
140
146
t := table .New ()
141
- hasErrorReason := r .Ota .ErrorReason != ""
142
147
143
- if hasErrorReason {
144
- t .SetHeader ("Device ID" , "Ota ID" , "Status" , "Started At" , "Ended At" , "Error Reason" )
148
+ succeeded := strings .ToLower (r .Ota .Status ) == "succeeded"
149
+ hasError := r .Ota .ErrorReason != "" || ! succeeded
150
+
151
+ if hasError {
152
+ t .SetHeader ("Device ID" , "Ota ID" , "Status" , "Started At" , "Ended At" , "Error Reason" , "Retry Attempt" )
145
153
} else {
146
154
t .SetHeader ("Device ID" , "Ota ID" , "Status" , "Started At" , "Ended At" )
147
155
}
148
156
149
157
// Now print the table
150
158
line := []any {r .Ota .DeviceID , r .Ota .ID , r .Ota .MapStatus (), formatHumanReadableTs (r .Ota .StartedAt ), formatHumanReadableTs (r .Ota .EndedAt )}
151
- if hasErrorReason {
159
+ if hasError {
152
160
line = append (line , r .Ota .ErrorReason )
161
+ line = append (line , strconv .FormatInt (r .RetryAttempt , 10 ))
153
162
}
154
163
t .AddRow (line ... )
155
164
@@ -160,22 +169,37 @@ func (r OtaStatusDetail) String() string {
160
169
t = table .New ()
161
170
t .SetHeader ("Time" , "Status" , "Detail" )
162
171
fwSize := int64 (0 )
163
- if r .FirmwareSize != nil {
164
- fwSize = * r .FirmwareSize
172
+ if r .FirmwareSize > 0 {
173
+ fwSize = r .FirmwareSize
174
+ }
175
+
176
+ firstTS := formatHumanReadableTs (r .Details [0 ].Timestamp )
177
+ if ! containsResetState (r .Details ) && ! hasError {
178
+ t .AddRow (firstTS , "Flash" , "" )
165
179
}
180
+
181
+ hasReachedFlashState := hasReachedFlashState (r .Details , succeeded )
166
182
for _ , s := range r .Details {
167
- stateData := formatStateData (s .State , s .StateData , fwSize , hasReachedFlashState ( r . Details ) )
183
+ stateData := formatStateData (s .State , s .StateData , fwSize , hasReachedFlashState )
168
184
t .AddRow (formatHumanReadableTs (s .Timestamp ), upperCaseFirst (s .State ), stateData )
169
185
}
186
+
170
187
output += "\n Details:\n " + t .Render ()
171
188
}
172
189
173
190
return output
174
191
}
175
192
176
- func hasReachedFlashState (states []State ) bool {
193
+ func hasReachedFlashState (states []State , succeeded bool ) bool {
194
+ if succeeded {
195
+ return true
196
+ }
197
+ return containsResetState (states )
198
+ }
199
+
200
+ func containsResetState (states []State ) bool {
177
201
for _ , s := range states {
178
- if s .State == "flash" || s .State == "reboot" {
202
+ if strings . ToLower ( s .State ) == "flash" || strings . ToLower ( s .State ) == "reboot" {
179
203
return true
180
204
}
181
205
}
@@ -193,15 +217,15 @@ func formatStateData(state, data string, firmware_size int64, hasReceivedFlashSt
193
217
return data
194
218
}
195
219
if hasReceivedFlashState {
196
- return buildSimpleProgressBar (float64 (100 ))
220
+ return buildSimpleProgressBar (float64 (100 ), firmware_size )
197
221
}
198
222
percentage := (float64 (actualDownloadedData ) / float64 (firmware_size )) * 100
199
- return buildSimpleProgressBar (percentage )
223
+ return buildSimpleProgressBar (percentage , firmware_size )
200
224
}
201
225
return data
202
226
}
203
227
204
- func buildSimpleProgressBar (progress float64 ) string {
228
+ func buildSimpleProgressBar (progress float64 , fw_size int64 ) string {
205
229
progressInt := int (progress ) / 10
206
230
progressInt = progressInt * progressBarMultiplier
207
231
maxProgress := 10 * progressBarMultiplier
@@ -211,7 +235,9 @@ func buildSimpleProgressBar(progress float64) string {
211
235
bar .WriteString (strings .Repeat (" " , maxProgress - progressInt ))
212
236
bar .WriteString ("] " )
213
237
bar .WriteString (strconv .FormatFloat (progress , 'f' , 2 , 64 ))
214
- bar .WriteString ("%" )
238
+ bar .WriteString ("% (firmware size: " )
239
+ bar .WriteString (strconv .FormatInt (fw_size , 10 ))
240
+ bar .WriteString (" bytes)" )
215
241
return bar .String ()
216
242
}
217
243
0 commit comments