-
Notifications
You must be signed in to change notification settings - Fork 0
/
app.go
137 lines (120 loc) · 3.17 KB
/
app.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
package main
import (
"fmt"
"log"
"net/smtp"
"os"
"sync"
"time"
"github.com/stianeikeland/go-rpio/v4"
)
// Constants for config folder and files
const (
folderConfig = "config"
fileConfig = "./config/config.json"
fileSunscrn = "./config/sunscreen.json"
fileLightsensor = "./config/lightsensor.json"
folderLog = "logs"
fileLog = "./logs/logfile.log"
fileStats = "./logs/sunscreen_stats.csv"
fileLight = "./logs/light_stats.csv"
)
var (
ls = &LightSensor{}
s = &Sunscreen{}
config Config
)
var (
muSunscrn sync.Mutex
muLS sync.Mutex
muConf sync.Mutex
)
func init() {
// Check if log folder exists, else create
if _, err := os.Stat(folderLog); os.IsNotExist(err) {
os.Mkdir(folderLog, 4096)
}
// Check if log folder exists, else create
if _, err := os.Stat(folderConfig); os.IsNotExist(err) {
os.Mkdir(folderConfig, 4096)
}
}
// TODO: review global/local funcs and vars
func main() {
// TODO: check if below can be stored in a separate func
// Open logfile or create if not exists
f, err := os.OpenFile(fileLog, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
if err != nil {
log.Panic("Error opening log file:", err)
// TODO: remove log file and create new
}
defer f.Close()
log.SetOutput(f)
log.Println("--------Start of program--------")
// Open connection RPIO pins
rpio.Open()
loadConfig()
s.init()
updateStartStop(s, ls, 0)
log.Println("Starting monitor")
if ls != nil {
go ls.MonitorMove(s)
}
startServer()
}
// UpdateStartStop resets all start/stop to today + d (e.g. d=0 resets it to today.
func updateStartStop(s *Sunscreen, ls *LightSensor, d int) {
s.resetStartStop(d)
// Light sensor should start in time so at sunscreen start enough light has been gathered
muLS.Lock()
dur := time.Duration((max(ls.TimesGood, ls.TimesNeutral, ls.TimesBad)+ls.Outliers)/int(ls.Interval.Minutes())) * time.Minute
ls.Start = s.Start.Add(-dur)
ls.Stop = s.Stop.Add(time.Duration(30 * time.Minute))
muLS.Unlock()
}
// Max takes multiple int and returns the highest value. It always returns a minimum of zero.
func max(xi ...int) int {
var x int
for _, v := range xi {
if v > x {
x = v
}
}
return x
}
// Min takes multiple int and returns the highest value. It always returns a minimum of 100000000.
func min(xi ...int) int {
x := 100000000
for _, v := range xi {
if v < x {
x = v
}
}
return x
}
// SendMail sends mail to
func sendMail(subj, body string) {
if config.EnableMail {
//Format message
var msgTo string
for i, s := range config.MailTo {
if i != 0 {
msgTo = msgTo + ","
}
msgTo = msgTo + s
}
msg := []byte("To:" + msgTo + "\r\n" +
"Subject:" + subj + "\r\n" +
"\r\n" + body + "\r\n")
// Set up authentication information
auth := smtp.PlainAuth("", config.MailUser, config.MailPass, config.MailHost)
// Connect to the server, authenticate, set the sender and recipient,
// and send the email all in one step.
err := smtp.SendMail(fmt.Sprintf("%v:%v", config.MailHost, config.MailPort), auth, config.MailFrom, config.MailTo, msg)
if err != nil {
log.Println("Unable to send mail:", err)
return
}
log.Println("Send mail to", config.MailTo)
}
}