-
Notifications
You must be signed in to change notification settings - Fork 1
/
kindle.go
113 lines (101 loc) · 3.11 KB
/
kindle.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
package main
import (
"fmt"
"log"
"os/exec"
"regexp"
"runtime"
"strconv"
"time"
)
// Suspend device and use real time clock alarm to wake it up.
// If our wake up time is more or less 24 hours away, we can put it to
// sleep immediately. Otherwise, we will wait another 30 seconds, which enables us
// to abort the process.
func suspendToRam(duration int) {
if runtime.GOARCH != "arm" {
return // Skip if not on Kindle
}
cmd1 := exec.Command("sh", "-c", "echo \"\" > /sys/class/rtc/rtc1/wakealarm")
err1 := cmd1.Run()
if err1 != nil {
log.Fatal(err1)
}
cmd2 := exec.Command("sh", "-c", fmt.Sprintf("echo \"+%d\" > /sys/class/rtc/rtc1/wakealarm", duration))
err2 := cmd2.Run()
if err2 != nil {
log.Fatal(err2)
}
// Delay sleep process otherwise it gets suspended during rendering.
sleepDelay := 1
// If sleep time < 24hrs, the button has been pressed, so give extra time to abort the process.
if duration < 3600*24-60 {
sleepDelay = 30
}
log.Printf("Waiting %d seconds before going back to sleep", sleepDelay)
time.Sleep(time.Duration(sleepDelay) * time.Second)
log.Println("Suspending to RAM")
cmd3 := exec.Command("sh", "-c", "echo \"mem\" > /sys/power/state")
err3 := cmd3.Run()
if err3 != nil {
log.Fatal(err3)
}
}
func initPowersave() {
exec.Command("sh", "-c", "stop framework").Run()
exec.Command("sh", "-c", "initctl stop webreader >/dev/null 2>&1").Run()
exec.Command("sh", "-c", "echo powersave >/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor").Run()
exec.Command("sh", "-c", "lipc-set-prop com.lab126.powerd preventScreenSaver 1").Run()
}
func getBatteryLevel() string {
if runtime.GOARCH != "arm" {
return "100%" // Skip if not on Kindle
}
out, err := exec.Command("/usr/bin/gasgauge-info", "-c").Output()
state := string(out)
if err != nil {
log.Fatal(err)
}
return state
}
// Count seconds till next wake up time. Formatted as clock
// time in 24H format. E.g. 6, 30 means 6:30 AM.
func nextWakeup(now time.Time, hour int, minutes int) int {
yyyy, mm, dd := now.Date()
if now.Hour() > hour || now.Hour() == hour && now.Minute() >= minutes {
dd++ // Jump to tomorrow, if wakeup time has already passed.
}
tomorrow := time.Date(yyyy, mm, dd, hour, minutes, 0, 0, now.Location())
return int(tomorrow.Sub(now).Seconds())
}
func drawToScreen(imagePath string) {
if runtime.GOARCH != "arm" {
return // Skip if not on Kindle
}
err := exec.Command("/usr/sbin/eips", "-fg", imagePath).Run()
if err != nil {
log.Fatal(err)
}
}
// Draw a small black box in the left bottom corner of the screen
func drawLowBatteryIndicator() {
if runtime.GOARCH != "arm" {
return // Skip if not on Kindle
}
cmd := exec.Command("/usr/sbin/eips", "-d", "l=0,w=50,h=65")
err := cmd.Run()
if err != nil {
log.Fatal(err)
}
}
func parseBatteryLevel(state string) (int, error) {
re := regexp.MustCompile(`\d*%`)
value := re.FindString(state)
if value == "" {
err := fmt.Errorf("Could not parse battery level %s", state)
return -1, err
}
numericValue := value[:len(value)-1] // Ommit % manually, because golang Regex does not support lookarounds.
i, _ := strconv.Atoi(numericValue)
return i, nil
}