-
Notifications
You must be signed in to change notification settings - Fork 0
/
history.go
125 lines (108 loc) · 3.02 KB
/
history.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
// This file implements a history of measurements
package main
import (
"bytes"
"encoding/json"
"errors"
"fmt"
"io"
"log"
"os"
"time"
)
// History of measurements
var history []Measurement
// max number of history elements that are stored
const HISTORY_LENGTH = 24 * 4
// name of the file to store history in
const HISTORY_FILE = ".kpg_history"
// Load history from file into global variable
// The whole file is loaded, expecting it was written with the corresponding
// saveHistory function, that truncates numer of items appropriately
// Potential errors include reading data from a file and decoding the JSON
func loadHistory() error {
input, err := os.ReadFile(HISTORY_FILE)
if err != nil {
if !os.IsNotExist(err) {
log.Println("Error reading history file:", err)
return err
}
} else {
if err := json.NewDecoder(bytes.NewReader(input)).Decode(&history); err != nil {
if err != io.EOF {
log.Println("Error decoding history:", err)
return err
}
}
}
return nil
}
// Saves history to file, trunctating unnecessary elements
// Potential errors include encoding da data to JSON and writing to the file
func saveHistory() error {
// shorten history to max HISTORY_LENGTH entries
cap := len(history) - HISTORY_LENGTH
if cap > 0 {
history = history[cap:]
}
data, err := json.MarshalIndent(history, "", " ")
if err != nil {
log.Println("Error encoding history:", err)
return err
}
err = os.WriteFile(HISTORY_FILE, data, 0664)
if err != nil {
log.Println("Error writing history file:", err)
return err
}
return nil
}
//
// These two functions were planned to improve reporting, but are not in use
// yet - therefore commented them out for now to avoid any warnings
//
// func hasJustCrossedThreshold(m Measurement, threshold float64) bool {
// if m.Level <= threshold {
// return false
// }
// if len(history) == 0 {
// return true
// } else {
// return history[len(history)-1].Level < threshold
// }
// }
// func getDiffToLast(m Measurement) float64 {
// if len(history) == 0 {
// loadHistory()
// }
// if len(history) == 0 {
// return m.Level
// } else {
// return m.Level - history[len(history)-1].Level
// }
// }
func levelDifference(current Measurement, minutes int) (float64, error) {
if len(history) == 0 {
errMsg := "cannot determine difference - history is empty"
return 0.0, errors.New(errMsg)
}
searchTime := current.Timestamp.Add(-time.Minute * time.Duration(minutes))
matchIndex := -1
// history is sorted by timestamps - identify the biggest index for which
// the timestamp is maximum, but not bigger than searchtime
for i := 0; i < len(history); i++ {
ts := history[i].Timestamp
if !searchTime.Before(ts) {
matchIndex = i
}
}
if matchIndex == -1 {
// all entries in history have a timestamp bigger than searchtime
// we take the first elem
errMsg := fmt.Sprintf("cannot determine difference - all elems in history %v", searchTime)
return 0.0, errors.New(errMsg)
} else {
diff := current.Level - history[matchIndex].Level
return diff, nil
}
}