Mercurial > code > home > repos > homeauto
annotate service/laundry/laundry.go @ 905:b58c203e18fe
port to goweb
Ignore-this: ea5e9ea0a0c09d1f4a7980d6c79126d1
darcs-hash:20130831191235-312f9-32a3bbee5ec64018d4a19e151bb9c857c6f208ee
author | drewp <drewp@bigasterisk.com> |
---|---|
date | Sat, 31 Aug 2013 12:12:35 -0700 |
parents | 5758151d4e33 |
children | 5f432946ac9a |
rev | line source |
---|---|
899 | 1 package main |
2 | |
3 import ( | |
905 | 4 |
899 | 5 "log" |
6 "net/http" | |
7 "strconv" | |
901 | 8 "time" |
904
5758151d4e33
start switch to goweb, for improved incoming payload handling
drewp <drewp@bigasterisk.com>
parents:
903
diff
changeset
|
9 "net" |
5758151d4e33
start switch to goweb, for improved incoming payload handling
drewp <drewp@bigasterisk.com>
parents:
903
diff
changeset
|
10 "os" |
899 | 11 "encoding/json" |
904
5758151d4e33
start switch to goweb, for improved incoming payload handling
drewp <drewp@bigasterisk.com>
parents:
903
diff
changeset
|
12 "os/signal" |
899 | 13 "github.com/mrmorphic/hwio" |
904
5758151d4e33
start switch to goweb, for improved incoming payload handling
drewp <drewp@bigasterisk.com>
parents:
903
diff
changeset
|
14 "github.com/stretchr/goweb" |
5758151d4e33
start switch to goweb, for improved incoming payload handling
drewp <drewp@bigasterisk.com>
parents:
903
diff
changeset
|
15 "github.com/stretchr/goweb/context" |
899 | 16 ) |
17 | |
18 /* | |
19 hwio.DebugPinMap() wrote this: | |
20 | |
21 Pin 1: 3.3V, cap: | |
22 Pin 2: 5V, cap: | |
23 Pin 3: SDA,GPIO0 cap:output,input,input_pullup,input_pulldown | |
24 Pin 5: SCL,GPIO1 cap:output,input,input_pullup,input_pulldown | |
25 Pin 6: GROUND, cap: | |
26 Pin 7: GPIO4 cap:output,input,input_pullup,input_pulldown | |
27 Pin 8: TXD,GPIO14 cap:output,input,input_pullup,input_pulldown | |
28 Pin 10: RXD,GPIO15 cap:output,input,input_pullup,input_pulldown | |
29 Pin 11: GPIO17 cap:output,input,input_pullup,input_pulldown | |
30 Pin 12: GPIO18 cap:output,input,input_pullup,input_pulldown | |
31 Pin 13: GPIO21 cap:output,input,input_pullup,input_pulldown | |
32 Pin 15: GPIO22 cap:output,input,input_pullup,input_pulldown | |
33 Pin 16: GPIO23 cap:output,input,input_pullup,input_pulldown | |
34 Pin 18: GPIO24 cap:output,input,input_pullup,input_pulldown | |
35 Pin 19: MOSI,GPIO10 cap:output,input,input_pullup,input_pulldown | |
36 Pin 21: MISO,GPIO9 cap:output,input,input_pullup,input_pulldown | |
37 Pin 22: GPIO25 cap:output,input,input_pullup,input_pulldown | |
38 Pin 23: SCLK,GPIO11 cap:output,input,input_pullup,input_pulldown | |
39 Pin 24: CE0N,GPIO8 cap:output,input,input_pullup,input_pulldown | |
40 Pin 26: CE1N,GPIO7 cap:output,input,input_pullup,input_pulldown | |
41 */ | |
42 | |
43 type Pins struct { | |
44 InMotion, InSwitch3, InSwitch1, InSwitch2, OutLed, OutSpeaker, InDoorClosed, OutStrike hwio.Pin | |
45 LastOutLed, LastOutStrike int | |
46 } | |
47 | |
48 // hwio.GetPin with a panic instead of an error return | |
49 func GetPin(id string) hwio.Pin { | |
50 p, e := hwio.GetPin(id) | |
51 if e != nil { | |
52 panic(e) | |
53 } | |
54 return p | |
55 } | |
56 | |
57 func DigitalRead(p hwio.Pin) int { | |
58 v, err := hwio.DigitalRead(p) | |
59 if err != nil { | |
60 panic(err) | |
61 } | |
62 return v | |
63 } | |
64 | |
65 func SetupIo() Pins { | |
66 pins := Pins{ | |
67 InMotion: GetPin("GPIO0"), | |
68 InSwitch3: GetPin("GPIO1"), | |
69 InSwitch1: GetPin("GPIO4"), | |
70 InSwitch2: GetPin("GPIO17"), | |
71 OutLed: GetPin("GPIO21"), | |
72 OutSpeaker: GetPin("GPIO22"), | |
73 InDoorClosed: GetPin("GPIO10"), | |
74 OutStrike: GetPin("GPIO9"), | |
75 } | |
76 | |
903 | 77 if err := hwio.PinMode(pins.InMotion, hwio.INPUT_PULLUP); err != nil { panic(err) } |
78 if err := hwio.PinMode(pins.InSwitch1, hwio.INPUT_PULLUP); err != nil { panic(err) } | |
79 if err := hwio.PinMode(pins.InSwitch2, hwio.INPUT_PULLUP); err != nil { panic(err) } | |
80 if err := hwio.PinMode(pins.InSwitch3, hwio.INPUT_PULLUP); err != nil { panic(err) } | |
81 if err := hwio.PinMode(pins.InDoorClosed, hwio.INPUT_PULLUP); err != nil { panic(err) } | |
82 if err := hwio.PinMode(pins.OutLed, hwio.OUTPUT); err != nil { panic(err) } | |
83 if err := hwio.PinMode(pins.OutSpeaker, hwio.OUTPUT); err != nil { panic(err) } | |
84 if err := hwio.PinMode(pins.OutStrike, hwio.OUTPUT); err != nil { panic(err) } | |
899 | 85 return pins |
86 } | |
87 | |
901 | 88 |
899 | 89 func main() { |
90 pins := SetupIo() | |
91 | |
904
5758151d4e33
start switch to goweb, for improved incoming payload handling
drewp <drewp@bigasterisk.com>
parents:
903
diff
changeset
|
92 goweb.MapStatic("/static", "static") |
5758151d4e33
start switch to goweb, for improved incoming payload handling
drewp <drewp@bigasterisk.com>
parents:
903
diff
changeset
|
93 |
5758151d4e33
start switch to goweb, for improved incoming payload handling
drewp <drewp@bigasterisk.com>
parents:
903
diff
changeset
|
94 // this one needs to fail if the hardware is broken in |
5758151d4e33
start switch to goweb, for improved incoming payload handling
drewp <drewp@bigasterisk.com>
parents:
903
diff
changeset
|
95 // any way that we can determine, though I'm not sure |
5758151d4e33
start switch to goweb, for improved incoming payload handling
drewp <drewp@bigasterisk.com>
parents:
903
diff
changeset
|
96 // what that will mean on rpi |
5758151d4e33
start switch to goweb, for improved incoming payload handling
drewp <drewp@bigasterisk.com>
parents:
903
diff
changeset
|
97 goweb.MapStaticFile("/", "index.html") |
899 | 98 |
904
5758151d4e33
start switch to goweb, for improved incoming payload handling
drewp <drewp@bigasterisk.com>
parents:
903
diff
changeset
|
99 goweb.Map("GET", "/status", func(c context.Context) error { |
5758151d4e33
start switch to goweb, for improved incoming payload handling
drewp <drewp@bigasterisk.com>
parents:
903
diff
changeset
|
100 jsonEncode := json.NewEncoder(c.HttpResponseWriter()) |
899 | 101 jsonEncode.Encode(map[string]int{ |
102 "motion": DigitalRead(pins.InMotion), | |
103 "switch1": DigitalRead(pins.InSwitch1), | |
104 "switch2": DigitalRead(pins.InSwitch2), | |
105 "switch3": DigitalRead(pins.InSwitch3), | |
106 "doorClosed": DigitalRead(pins.InDoorClosed), | |
107 "led": pins.LastOutLed, | |
901 | 108 "strike": pins.LastOutStrike, |
899 | 109 }) |
904
5758151d4e33
start switch to goweb, for improved incoming payload handling
drewp <drewp@bigasterisk.com>
parents:
903
diff
changeset
|
110 return nil |
5758151d4e33
start switch to goweb, for improved incoming payload handling
drewp <drewp@bigasterisk.com>
parents:
903
diff
changeset
|
111 }) |
5758151d4e33
start switch to goweb, for improved incoming payload handling
drewp <drewp@bigasterisk.com>
parents:
903
diff
changeset
|
112 |
905 | 113 goweb.Map("PUT", "/led", func(c context.Context) error { |
114 body, err := c.RequestBody() | |
899 | 115 if err != nil { |
116 panic(err) | |
117 } | |
905 | 118 |
901 | 119 var level int |
120 if string(body) == "on" { | |
121 level = 1 | |
122 } else if string(body) == "off" { | |
123 level = 0 | |
124 } else { | |
905 | 125 http.Error(c.HttpResponseWriter(), "body must be 'on' or 'off'", http.StatusBadRequest) |
126 return nil | |
899 | 127 } |
128 | |
129 hwio.DigitalWrite(pins.OutLed, level) | |
130 pins.LastOutLed = level | |
905 | 131 http.Error(c.HttpResponseWriter(), "", http.StatusAccepted) |
132 return nil | |
133 }) | |
899 | 134 |
901 | 135 setStrike := func (level int) { |
136 hwio.DigitalWrite(pins.OutStrike, level) | |
137 pins.LastOutStrike = level | |
138 } | |
139 | |
905 | 140 goweb.Map("PUT", "/strike", func(c context.Context) error { |
141 body, err := c.RequestBody() | |
901 | 142 if err != nil { |
143 panic(err) | |
144 } | |
905 | 145 |
146 level, err2 := strconv.Atoi(string(body[:])) | |
147 if err2 != nil { | |
148 http.Error(c.HttpResponseWriter(), "body must be '0' or '1'", http.StatusBadRequest) | |
149 return nil | |
150 } | |
151 | |
901 | 152 setStrike(level) |
905 | 153 http.Error(c.HttpResponseWriter(), "", http.StatusAccepted) |
154 return nil | |
155 }) | |
901 | 156 |
905 | 157 goweb.Map("PUT", "/strike/temporaryUnlock", func(c context.Context) error { |
158 seconds, err2 := strconv.ParseFloat(c.FormValue("seconds"), 32) | |
901 | 159 if err2 != nil { |
905 | 160 http.Error(c.HttpResponseWriter(), "seconds must be a float", http.StatusBadRequest) |
161 return nil | |
901 | 162 } |
163 | |
164 // This is not correctly reentrant. There should be a | |
165 // stack of temporary effects that unpop correctly, | |
166 // and status should show you any running effects. | |
167 setStrike(1) | |
168 go func() { | |
169 time.Sleep(time.Duration(seconds * float64(time.Second))) | |
170 setStrike(0) | |
171 }() | |
905 | 172 http.Error(c.HttpResponseWriter(), "", http.StatusAccepted) |
173 return nil | |
174 }) | |
901 | 175 |
905 | 176 goweb.Map("PUT", "/speaker/beep", func(c context.Context) error { |
901 | 177 // queue a beep |
905 | 178 http.Error(c.HttpResponseWriter(), "", http.StatusAccepted) |
179 return nil | |
180 }) | |
181 | |
904
5758151d4e33
start switch to goweb, for improved incoming payload handling
drewp <drewp@bigasterisk.com>
parents:
903
diff
changeset
|
182 |
5758151d4e33
start switch to goweb, for improved incoming payload handling
drewp <drewp@bigasterisk.com>
parents:
903
diff
changeset
|
183 address := ":8081" |
901 | 184 |
904
5758151d4e33
start switch to goweb, for improved incoming payload handling
drewp <drewp@bigasterisk.com>
parents:
903
diff
changeset
|
185 s := &http.Server{ |
5758151d4e33
start switch to goweb, for improved incoming payload handling
drewp <drewp@bigasterisk.com>
parents:
903
diff
changeset
|
186 Addr: address, |
5758151d4e33
start switch to goweb, for improved incoming payload handling
drewp <drewp@bigasterisk.com>
parents:
903
diff
changeset
|
187 Handler: goweb.DefaultHttpHandler(), |
5758151d4e33
start switch to goweb, for improved incoming payload handling
drewp <drewp@bigasterisk.com>
parents:
903
diff
changeset
|
188 ReadTimeout: 10 * time.Second, |
5758151d4e33
start switch to goweb, for improved incoming payload handling
drewp <drewp@bigasterisk.com>
parents:
903
diff
changeset
|
189 WriteTimeout: 10 * time.Second, |
5758151d4e33
start switch to goweb, for improved incoming payload handling
drewp <drewp@bigasterisk.com>
parents:
903
diff
changeset
|
190 MaxHeaderBytes: 1 << 20, |
5758151d4e33
start switch to goweb, for improved incoming payload handling
drewp <drewp@bigasterisk.com>
parents:
903
diff
changeset
|
191 } |
5758151d4e33
start switch to goweb, for improved incoming payload handling
drewp <drewp@bigasterisk.com>
parents:
903
diff
changeset
|
192 |
5758151d4e33
start switch to goweb, for improved incoming payload handling
drewp <drewp@bigasterisk.com>
parents:
903
diff
changeset
|
193 log.Printf("Listening on port %s", address) |
5758151d4e33
start switch to goweb, for improved incoming payload handling
drewp <drewp@bigasterisk.com>
parents:
903
diff
changeset
|
194 listener, listenErr := net.Listen("tcp", address) |
5758151d4e33
start switch to goweb, for improved incoming payload handling
drewp <drewp@bigasterisk.com>
parents:
903
diff
changeset
|
195 |
5758151d4e33
start switch to goweb, for improved incoming payload handling
drewp <drewp@bigasterisk.com>
parents:
903
diff
changeset
|
196 log.Printf("%s", goweb.DefaultHttpHandler()) |
5758151d4e33
start switch to goweb, for improved incoming payload handling
drewp <drewp@bigasterisk.com>
parents:
903
diff
changeset
|
197 |
5758151d4e33
start switch to goweb, for improved incoming payload handling
drewp <drewp@bigasterisk.com>
parents:
903
diff
changeset
|
198 if listenErr != nil { |
5758151d4e33
start switch to goweb, for improved incoming payload handling
drewp <drewp@bigasterisk.com>
parents:
903
diff
changeset
|
199 log.Fatalf("Could not listen: %s", listenErr) |
899 | 200 } |
904
5758151d4e33
start switch to goweb, for improved incoming payload handling
drewp <drewp@bigasterisk.com>
parents:
903
diff
changeset
|
201 |
5758151d4e33
start switch to goweb, for improved incoming payload handling
drewp <drewp@bigasterisk.com>
parents:
903
diff
changeset
|
202 c := make(chan os.Signal, 1) |
5758151d4e33
start switch to goweb, for improved incoming payload handling
drewp <drewp@bigasterisk.com>
parents:
903
diff
changeset
|
203 signal.Notify(c, os.Interrupt) |
5758151d4e33
start switch to goweb, for improved incoming payload handling
drewp <drewp@bigasterisk.com>
parents:
903
diff
changeset
|
204 go func() { |
5758151d4e33
start switch to goweb, for improved incoming payload handling
drewp <drewp@bigasterisk.com>
parents:
903
diff
changeset
|
205 for _ = range c { |
5758151d4e33
start switch to goweb, for improved incoming payload handling
drewp <drewp@bigasterisk.com>
parents:
903
diff
changeset
|
206 |
5758151d4e33
start switch to goweb, for improved incoming payload handling
drewp <drewp@bigasterisk.com>
parents:
903
diff
changeset
|
207 // sig is a ^C, handle it |
5758151d4e33
start switch to goweb, for improved incoming payload handling
drewp <drewp@bigasterisk.com>
parents:
903
diff
changeset
|
208 |
5758151d4e33
start switch to goweb, for improved incoming payload handling
drewp <drewp@bigasterisk.com>
parents:
903
diff
changeset
|
209 // stop the HTTP server |
5758151d4e33
start switch to goweb, for improved incoming payload handling
drewp <drewp@bigasterisk.com>
parents:
903
diff
changeset
|
210 log.Print("Stopping the server...") |
5758151d4e33
start switch to goweb, for improved incoming payload handling
drewp <drewp@bigasterisk.com>
parents:
903
diff
changeset
|
211 listener.Close() |
5758151d4e33
start switch to goweb, for improved incoming payload handling
drewp <drewp@bigasterisk.com>
parents:
903
diff
changeset
|
212 |
5758151d4e33
start switch to goweb, for improved incoming payload handling
drewp <drewp@bigasterisk.com>
parents:
903
diff
changeset
|
213 /* |
5758151d4e33
start switch to goweb, for improved incoming payload handling
drewp <drewp@bigasterisk.com>
parents:
903
diff
changeset
|
214 Tidy up and tear down |
5758151d4e33
start switch to goweb, for improved incoming payload handling
drewp <drewp@bigasterisk.com>
parents:
903
diff
changeset
|
215 */ |
5758151d4e33
start switch to goweb, for improved incoming payload handling
drewp <drewp@bigasterisk.com>
parents:
903
diff
changeset
|
216 log.Print("Tearing down...") |
5758151d4e33
start switch to goweb, for improved incoming payload handling
drewp <drewp@bigasterisk.com>
parents:
903
diff
changeset
|
217 |
5758151d4e33
start switch to goweb, for improved incoming payload handling
drewp <drewp@bigasterisk.com>
parents:
903
diff
changeset
|
218 // TODO: tidy code up here |
5758151d4e33
start switch to goweb, for improved incoming payload handling
drewp <drewp@bigasterisk.com>
parents:
903
diff
changeset
|
219 |
5758151d4e33
start switch to goweb, for improved incoming payload handling
drewp <drewp@bigasterisk.com>
parents:
903
diff
changeset
|
220 log.Fatal("Finished - bye bye. ;-)") |
5758151d4e33
start switch to goweb, for improved incoming payload handling
drewp <drewp@bigasterisk.com>
parents:
903
diff
changeset
|
221 |
5758151d4e33
start switch to goweb, for improved incoming payload handling
drewp <drewp@bigasterisk.com>
parents:
903
diff
changeset
|
222 } |
5758151d4e33
start switch to goweb, for improved incoming payload handling
drewp <drewp@bigasterisk.com>
parents:
903
diff
changeset
|
223 }() |
5758151d4e33
start switch to goweb, for improved incoming payload handling
drewp <drewp@bigasterisk.com>
parents:
903
diff
changeset
|
224 log.Fatalf("Error in Serve: %s", s.Serve(listener)) |
5758151d4e33
start switch to goweb, for improved incoming payload handling
drewp <drewp@bigasterisk.com>
parents:
903
diff
changeset
|
225 |
899 | 226 } |