-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathburglarm.go
137 lines (119 loc) · 2.48 KB
/
burglarm.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 (
"github.com/chbmuc/lirc"
"github.com/stianeikeland/go-rpio"
"log"
"os"
"os/signal"
"syscall"
"time"
)
const (
// Burglarm States
TRIGGERED = iota
ARMED
DISARMED
)
type Burglarm struct {
buzzerPin rpio.Pin // PIN 15, GPIO 22
pirPin rpio.Pin // PIN 16, GPIO 23
state uint8
action chan uint8
stop chan bool
}
func (b *Burglarm) pollPir() {
// Keep reading PIR pin for trigger
for {
if b.pirPin.Read() == rpio.High {
b.action <- TRIGGERED
return
}
}
}
func (b *Burglarm) beep() {
b.buzzerPin.High()
time.Sleep(time.Millisecond * 500)
b.buzzerPin.Low()
}
func (b *Burglarm) start() {
for {
select {
case action := <-b.action:
switch action {
case ARMED:
log.Println("Armed")
// Start monitoring after 5 seconds the device is turned on
time.AfterFunc(5*time.Second, func() { b.pollPir() })
case DISARMED:
log.Println("Disarmed")
b.buzzerPin.Low()
case TRIGGERED:
log.Println("Triggered")
// Set alarm pin high
b.buzzerPin.High()
}
b.state = action
case <-b.stop:
b.buzzerPin.Low()
log.Println("stopping service")
b.stop <- true
return
}
}
}
func (b *Burglarm) terminate() {
b.stop <- true
<-b.stop // block until previous stop is processed
}
func (b *Burglarm) remoteKey(event lirc.Event) {
// Long key press triggers event twice
// Ignore long key presses
if event.Repeat > 0 {
return
}
log.Println(event.Button)
b.beep()
if b.state == DISARMED {
// Rearm on key press of remote
log.Println("ARM")
b.action <- ARMED
} else {
// Disarm on key press of remote
log.Println("DISARM")
b.action <- DISARMED
}
}
func main() {
// Open memory range for GPIO access in /dev/mem
err := rpio.Open()
if err != nil {
log.Println(err)
}
defer rpio.Close()
burglarm := &Burglarm{
action: make(chan uint8),
stop: make(chan bool),
}
// Init GPIO Pins
burglarm.buzzerPin = rpio.Pin(22)
burglarm.buzzerPin.Mode(rpio.Output)
burglarm.pirPin = rpio.Pin(23)
burglarm.pirPin.Mode(rpio.Input)
// Init IR
ir, err := lirc.Init("/var/run/lirc/lircd")
if err != nil {
log.Println("LIRC Error", err)
}
ir.Handle("", "KEY_POWER", burglarm.remoteKey)
go ir.Run()
// Start Service
log.Println("Starting Service")
go burglarm.start()
burglarm.action <- ARMED // Arm alarm on start
// Stop Service
// Handle SIGINT and SIGTERM
ch := make(chan os.Signal)
signal.Notify(ch, syscall.SIGINT, syscall.SIGTERM)
log.Println(<-ch) // blocks main
burglarm.terminate()
}