1package main
2
3import (
4 "fmt"
5 "log"
6 "syscall"
7 "time"
8
9 "tokei.pi/extras"
10 "tokei.pi/renderer"
11 "tokei.pi/screendriver"
12 "tokei.pi/screenfader"
13 "tokei.pi/ui"
14 "tokei.pi/weather"
15
16 "github.com/warthog618/gpiod"
17 "github.com/warthog618/gpiod/device/rpi"
18)
19
20func checkError(error error) {
21 if error != nil {
22 log.Fatal(error)
23 }
24}
25
26func checkGPIOInitError(error error) {
27 if error != nil {
28 log.Fatal(fmt.Sprintf("RequestLine returned error: %s\n", error))
29 if error == syscall.Errno(22) {
30 log.Fatal("Note that the WithPullUp option requires kernel V5.5 or later - check your kernel version.")
31 }
32 }
33}
34
35/*
36func checkIfBothButtonsArePressed(currentButton string) bool {
37 if extras.LeftButtonState == true {
38 if extras.RightButtonState == true {
39 fmt.Println("Both buttons pressed!")
40 ui.UISelectionIndex = ui.UISelectionIndexBuffer
41 if ui.UIDisplayedMenu == 1 {
42 selectBook()
43 fmt.Println("Loaded a book!")
44 return true
45 } else if ui.UIDisplayedMenu == 2 {
46 appdata.SaveBookData(phnparser.LoadedBookHash, ui.UISelectionIndex)
47 ui.RenderUI()
48 fmt.Println("Saved the position!")
49 return true
50 }
51 }
52 }
53 return false
54}*/
55
56func leftEventHandler(evt gpiod.LineEvent) {
57 edge := "rising"
58 extras.LeftButtonState = false
59 if evt.Type == gpiod.LineEventFallingEdge {
60 edge = "falling"
61 extras.LeftButtonState = true
62 extras.LeftButtonPressedTime = time.Now()
63 }
64 if edge == "rising" {
65 if time.Now().Sub(extras.LeftButtonPressedTime).Seconds() >= extras.NavigationHoldDuration {
66 fmt.Println("Back nav placeholder")
67 }
68 }
69 if edge == "falling" {
70 /*
71 if checkIfBothButtonsArePressed("left") {
72 return
73 }*/
74 fmt.Println("Left button pressed!")
75 screenfader.ClickRegistered()
76 ui.UIDisplayedMenu--
77 if ui.UIDisplayedMenu < 1 {
78 ui.UIDisplayedMenu = ui.UIWidgetCount
79 }
80 ui.UITopBarTitle = fmt.Sprintf("Widget set %d", ui.UIDisplayedMenu)
81 ui.RenderUI()
82 }
83}
84
85func rightEventHandler(evt gpiod.LineEvent) {
86 edge := "rising"
87 extras.RightButtonState = false
88 if evt.Type == gpiod.LineEventFallingEdge {
89 edge = "falling"
90 extras.RightButtonState = true
91 }
92 if edge == "falling" {
93 /*
94 if checkIfBothButtonsArePressed("right") {
95 return
96 }*/
97 fmt.Println("Right button pressed!")
98 screenfader.ClickRegistered()
99 ui.UIDisplayedMenu++
100 if ui.UIDisplayedMenu > ui.UIWidgetCount {
101 ui.UIDisplayedMenu = 1
102 }
103 ui.UITopBarTitle = fmt.Sprintf("Widget set %d", ui.UIDisplayedMenu)
104 ui.RenderUI()
105 }
106}
107
108func UIMainloop() {
109 for true {
110 // Rerender UI every second
111 time.Sleep(time.Second)
112 ui.RenderUI()
113 }
114}
115
116func UIWeatherMainloop() {
117 for true {
118 weather.UpdateCurrentWeather()
119 time.Sleep(240 * time.Second)
120 }
121}
122
123func ScreenFaderMainloop() {
124 for true {
125 screenfader.AdaptDisplayBrightness()
126 timeSinceLastClick := int(time.Now().UnixMilli() - screenfader.LastClickTimestamp)
127 if timeSinceLastClick < screenfader.ScreenFadeDelay*1000 {
128 time.Sleep(100 * time.Millisecond)
129 } else if timeSinceLastClick < screenfader.ScreenFadeDelay*1000+screenfader.ScreenFadeDuration*1000 {
130 time.Sleep(17 * time.Millisecond)
131 } else {
132 time.Sleep(1000 * time.Millisecond)
133 }
134 }
135}
136
137func main() {
138 // Config
139 // Input
140 leftButtonPinRef := rpi.J8p11
141 rightButtonPinRef := rpi.J8p13
142 debouncingPeriod := 10 * time.Millisecond
143 extras.NavigationHoldDuration = 3
144 // Screen
145 renderer.ScreenCount = 2
146 renderer.ScreenWidth = 128
147 renderer.ScreenHeight = 64
148 // UI
149 ui.BuildVersion = "V2022.07.11"
150 ui.UIMargin = 1
151 ui.UITopBarHeight = 10
152 ui.UILineHeight = 8
153 ui.UIFontHorizontalSpacing = 9
154 ui.UIMaxBookLines = 6
155 ui.UIWidgetCount = 4
156 // Display Driver
157 screendriver.I2CBuses = []string{"1", "4"}
158 // Extras
159 extras.CloudflareIP = "1.1.1.1"
160 // Weather
161 weather.OpenWeatherMapAPIKey = "2ee79601c807b825fa622addcb4d9b57"
162 weather.CityOfObservation = "Paris, FR"
163 weather.Latitude = 48.834590
164 weather.Longitude = 2.398260
165 // Code
166 // GPIO init
167 l, err := gpiod.RequestLine("gpiochip0", leftButtonPinRef, gpiod.WithPullUp, gpiod.WithBothEdges, gpiod.WithEventHandler(leftEventHandler), gpiod.WithDebounce(debouncingPeriod))
168 checkGPIOInitError(err)
169 defer l.Close()
170 r, err := gpiod.RequestLine("gpiochip0", rightButtonPinRef, gpiod.WithPullUp, gpiod.WithBothEdges, gpiod.WithEventHandler(rightEventHandler), gpiod.WithDebounce(debouncingPeriod))
171 checkGPIOInitError(err)
172 defer r.Close()
173 // Displays init
174 screendriver.InitializeDisplays()
175 // Renderer init
176 renderer.InitFrameBuffers()
177 // Boot screen show
178 ui.UIDisplayedMenu = 0
179 ui.RenderUI()
180 ui.UIConnectedToInternet = extras.PingCloudflare()
181 go UIMainloop()
182 go UIWeatherMainloop()
183 go ScreenFaderMainloop()
184 // Ping every 60s
185 for true {
186 time.Sleep(time.Minute)
187 ui.UIConnectedToInternet = extras.PingCloudflare()
188 }
189
190}