-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.go
127 lines (99 loc) · 2.83 KB
/
main.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
package main
import (
"encoding/binary"
"fmt"
"io/ioutil"
"strconv"
"strings"
"time"
"github.com/ChristianHering/Thermostat/utils"
waveshare "github.com/ChristianHering/WaveShare"
"golang.org/x/exp/io/i2c"
)
var i2cDevice *i2c.Device
func main() {
err := utils.SetupUtils()
if err != nil {
panic(err)
}
i2cDevice, err = i2c.Open(&i2c.Devfs{Dev: "/dev/i2c-1"}, 0x48)
if err != nil {
panic(err)
}
for {
displayLoop() //Recovers from panics, then restarts displayLoop
}
}
func displayLoop() {
defer func() {
if err := recover(); err != nil {
utils.LogError(fmt.Sprintf("%+v", err))
}
}()
var sensorTemps []float64
var rData Data
sensorTemps = append(sensorTemps, getTemp())
for {
weatherData, err := getWeatherData()
if err != nil {
panic(err)
}
//This is the number of times our program refreshes
//local data before calling OpenWeather Map's API again.
//
//According to their website, OpenWeather Map updates data
//for a given location no more than once every 10 minutes.
for i := 0; i < 5; i++ {
t, err := ioutil.ReadFile("/sys/class/thermal/thermal_zone0/temp") //CPU temp readout
if err != nil {
utils.LogError(err.Error())
}
temp, err := strconv.Atoi(strings.TrimSuffix(string(t), "\n"))
if err != nil {
temp = 0 //If the temperature read/conversion fails, set it to a default value
utils.LogError(err.Error())
}
t, err = ioutil.ReadFile("/proc/loadavg") //CPU load readout
if err != nil {
utils.LogError(err.Error())
}
rData.RenderTime = time.Now().Format("3:04pm")
rData.CPUTemp = strconv.FormatFloat(float64(temp/1000), 'f', -1, 64)
rData.CPUUsage = strings.Split(string(t), " ")
rData.SensorTemp = mean(sensorTemps)
img := render(weatherData, rData)
waveshare.Initialize()
waveshare.DisplayImage(img)
waveshare.Sleep()
for i := 0; i < 10; i++ { //Average 10 temperature readings per minute to smooth the result out
sensorTemps = append(sensorTemps, getTemp())
if len(sensorTemps) > 10 {
sensorTemps = sensorTemps[1:]
}
time.Sleep(6 * time.Second)
}
}
}
}
//Returns the temperature from our TMP117 in fahrenheit
//
//Generally speaking, this function shouldn't be
//called more than once per second. For faster updates,
//more sensors should be used, sensor settings should
//be changed, or functions should cache readings.
func getTemp() float64 {
var b = []byte{0, 0}
err := i2cDevice.ReadReg(0x00, b)
if err != nil {
panic(err)
}
return (float64(binary.BigEndian.Uint16(b))*0.0078125)*1.8 + 32
}
//Calculates the average of a given array
func mean(arr []float64) float64 {
var sum float64
for i := 0; i < len(arr); i++ {
sum += arr[i]
}
return sum / float64(len(arr))
}