Skip to content

Commit 2388b1e

Browse files
committed
React to lid open via acpi_listen
1 parent e7b5538 commit 2388b1e

5 files changed

Lines changed: 101 additions & 5 deletions

File tree

acpi_listen.go

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
package main
2+
3+
import (
4+
"bufio"
5+
"os/exec"
6+
)
7+
8+
// AcpiEvent returns a channel from which you can receive ACPI events
9+
// by reading from acpi_listen output.
10+
// Arguments are like printed by acpi_listen, for example:
11+
//
12+
// "button/lid LID close"
13+
// "button/lid LID open"
14+
// "video/brightnessdown BRTDN 00000087 00000000"
15+
// "wmi PNP0C14:05 000000d0 00000000"
16+
//
17+
// Passing one or more of these strings will make the returned channel
18+
// only react to the corresponding events. Passing "" will make it react
19+
// to all events.
20+
// The item returned from the channel will be the ACPI event string in
21+
// the same format as the filter argument.
22+
// AcpiEvent will create a goroutine that spawns an acpi_listen instance
23+
// and wait for output from it to fill the event channel.
24+
func AcpiEvent(cmdName string, watchedEvent string) (eventsOut chan string, err error) {
25+
eventsOut = make(chan string, 100)
26+
cmd := exec.Command(cmdName)
27+
out, err := cmd.StdoutPipe()
28+
if err != nil {
29+
return nil, err
30+
}
31+
scanner := bufio.NewScanner(out)
32+
err = cmd.Start()
33+
if err != nil {
34+
return nil, err
35+
}
36+
go func() {
37+
for scanner.Scan() {
38+
text := scanner.Text()
39+
if text == watchedEvent || watchedEvent == "" {
40+
line := scanner.Text()
41+
eventsOut <- line
42+
}
43+
}
44+
}()
45+
return eventsOut, err
46+
}

acpi_listen_test.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package main
2+
3+
import (
4+
"testing"
5+
)
6+
7+
const mockAcpiListen = "./mock_acpi_listen.sh"
8+
9+
func TestAcpiEvent(t *testing.T) {
10+
acpiChan, _ := AcpiEvent(mockAcpiListen, acpiLidOpenEvent)
11+
event := <-acpiChan
12+
13+
if event != acpiLidOpenEvent {
14+
t.Errorf("got %q, want %q", event, acpiLidOpenEvent)
15+
}
16+
}

clock.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@ import (
77
"time"
88
)
99

10+
const (
11+
acpiLidOpenEvent = "button/lid LID open"
12+
acpiListenCmd = "acpi_listen"
13+
)
14+
1015
// repeatUntilInterrupt runs the given function every interval.
1116
// It will return whenever one of the signals in interruptSignals is received.
1217
func repeatUntilInterrupt(callback func(), interval time.Duration, interruptSignals ...os.Signal) {
@@ -16,10 +21,17 @@ func repeatUntilInterrupt(callback func(), interval time.Duration, interruptSign
1621
sigc := make(chan os.Signal, 1)
1722
signal.Notify(sigc, interruptSignals...)
1823
quit := make(chan bool)
24+
acpiEvent, acpiErr := AcpiEvent(acpiListenCmd, acpiLidOpenEvent)
25+
if acpiErr != nil {
26+
slog.Warn("ACPI event listener could not be started", "error", acpiErr)
27+
}
1928
for {
2029
select {
2130
case <-ticker.C:
2231
callback()
32+
case <-acpiEvent:
33+
slog.Info("acpi event received")
34+
callback()
2335
case sig := <-sigc:
2436
slog.Debug("received signal", "signal", sig)
2537
go func() { quit <- true }()

main_test.go

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,15 @@ package main
22

33
import (
44
"flag"
5-
"io"
6-
"log/slog"
75
"strconv"
86
"strings"
97
"testing"
108
"time"
119
)
1210

13-
func TestMain(t *testing.T) {
14-
slog.SetDefault(slog.New(slog.NewTextHandler(io.Discard, nil)))
15-
}
11+
//func TestMain(t *testing.T) {
12+
// slog.SetDefault(slog.New(slog.NewTextHandler(io.Discard, nil)))
13+
//}
1614

1715
type roundFloatTestCase struct {
1816
in float64

mock_acpi_listen.sh

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
#!/bin/bash
2+
3+
output=(
4+
"video/brightnessdown BRTDN 00000087 00000000"
5+
"video/brightnessup BRTUP 00000086 00000000"
6+
"video/brightnessdown BRTDN 00000087 00000000"
7+
"video/brightnessup BRTUP 00000086 00000000"
8+
"button/lid LID close"
9+
"button/lid LID open"
10+
"video/brightnessdown BRTDN 00000087 00000000"
11+
"wmi PNP0C14:05 000000d0 00000000"
12+
"video/brightnessup BRTUP 00000086 00000000"
13+
"wmi PNP0C14:05 000000d0 00000000"
14+
"video/brightnessdown BRTDN 00000087 00000000"
15+
"wmi PNP0C14:05 000000d0 00000000"
16+
)
17+
18+
for line in "${output[@]}"
19+
do
20+
sleep 0.1
21+
echo "$line"
22+
done
23+
24+
sleep 10000000000000

0 commit comments

Comments
 (0)