Mercurial > code > home > repos > homeauto
view service/laundry/laundry.go @ 903:254847c0f9a6
merge
Ignore-this: 2c3507eccaeeceee5027f01fa0171538
darcs-hash:20130831173904-312f9-d4a19e23fd83d8bfdfcfd2e2f1319595669ad2c0
author | drewp <drewp@bigasterisk.com> |
---|---|
date | Sat, 31 Aug 2013 10:39:04 -0700 |
parents | c06fdb61157f |
children | 3c583603f261 |
line wrap: on
line source
package main import ( "io/ioutil" "log" "net/http" "strconv" "time" "encoding/json" "github.com/bmizerany/pat" "github.com/mrmorphic/hwio" ) /* hwio.DebugPinMap() wrote this: Pin 1: 3.3V, cap: Pin 2: 5V, cap: Pin 3: SDA,GPIO0 cap:output,input,input_pullup,input_pulldown Pin 5: SCL,GPIO1 cap:output,input,input_pullup,input_pulldown Pin 6: GROUND, cap: Pin 7: GPIO4 cap:output,input,input_pullup,input_pulldown Pin 8: TXD,GPIO14 cap:output,input,input_pullup,input_pulldown Pin 10: RXD,GPIO15 cap:output,input,input_pullup,input_pulldown Pin 11: GPIO17 cap:output,input,input_pullup,input_pulldown Pin 12: GPIO18 cap:output,input,input_pullup,input_pulldown Pin 13: GPIO21 cap:output,input,input_pullup,input_pulldown Pin 15: GPIO22 cap:output,input,input_pullup,input_pulldown Pin 16: GPIO23 cap:output,input,input_pullup,input_pulldown Pin 18: GPIO24 cap:output,input,input_pullup,input_pulldown Pin 19: MOSI,GPIO10 cap:output,input,input_pullup,input_pulldown Pin 21: MISO,GPIO9 cap:output,input,input_pullup,input_pulldown Pin 22: GPIO25 cap:output,input,input_pullup,input_pulldown Pin 23: SCLK,GPIO11 cap:output,input,input_pullup,input_pulldown Pin 24: CE0N,GPIO8 cap:output,input,input_pullup,input_pulldown Pin 26: CE1N,GPIO7 cap:output,input,input_pullup,input_pulldown */ type Pins struct { InMotion, InSwitch3, InSwitch1, InSwitch2, OutLed, OutSpeaker, InDoorClosed, OutStrike hwio.Pin LastOutLed, LastOutStrike int } // hwio.GetPin with a panic instead of an error return func GetPin(id string) hwio.Pin { p, e := hwio.GetPin(id) if e != nil { panic(e) } return p } func DigitalRead(p hwio.Pin) int { v, err := hwio.DigitalRead(p) if err != nil { panic(err) } return v } func SetupIo() Pins { pins := Pins{ InMotion: GetPin("GPIO0"), InSwitch3: GetPin("GPIO1"), InSwitch1: GetPin("GPIO4"), InSwitch2: GetPin("GPIO17"), OutLed: GetPin("GPIO21"), OutSpeaker: GetPin("GPIO22"), InDoorClosed: GetPin("GPIO10"), OutStrike: GetPin("GPIO9"), } if err := hwio.PinMode(pins.InMotion, hwio.INPUT_PULLUP); err != nil { panic(err) } if err := hwio.PinMode(pins.InSwitch1, hwio.INPUT_PULLUP); err != nil { panic(err) } if err := hwio.PinMode(pins.InSwitch2, hwio.INPUT_PULLUP); err != nil { panic(err) } if err := hwio.PinMode(pins.InSwitch3, hwio.INPUT_PULLUP); err != nil { panic(err) } if err := hwio.PinMode(pins.InDoorClosed, hwio.INPUT_PULLUP); err != nil { panic(err) } if err := hwio.PinMode(pins.OutLed, hwio.OUTPUT); err != nil { panic(err) } if err := hwio.PinMode(pins.OutSpeaker, hwio.OUTPUT); err != nil { panic(err) } if err := hwio.PinMode(pins.OutStrike, hwio.OUTPUT); err != nil { panic(err) } return pins } func booleanBody(w http.ResponseWriter, r *http.Request) (level int, err error) { body, err := ioutil.ReadAll(r.Body) if err != nil { panic(err) } level, err2 := strconv.Atoi(string(body[:])) if err2 != nil { http.Error(w, "body must be '0' or '1'", http.StatusBadRequest) return 0, err } return level, nil } func main() { pins := SetupIo() m := pat.New() m.Get("/", http.HandlerFunc(func (w http.ResponseWriter, r *http.Request) { // this one needs to fail if the hardware is broken in // any way that we can determine, though I'm not sure // what that will mean on rpi http.ServeFile(w, r, "index.html") })); m.Get("/static/:any", http.FileServer(http.Dir("./"))); m.Get("/status", http.HandlerFunc(func (w http.ResponseWriter, r *http.Request) { jsonEncode := json.NewEncoder(w) jsonEncode.Encode(map[string]int{ "motion": DigitalRead(pins.InMotion), "switch1": DigitalRead(pins.InSwitch1), "switch2": DigitalRead(pins.InSwitch2), "switch3": DigitalRead(pins.InSwitch3), "doorClosed": DigitalRead(pins.InDoorClosed), "led": pins.LastOutLed, "strike": pins.LastOutStrike, }) })); m.Put("/led", http.HandlerFunc(func (w http.ResponseWriter, r *http.Request) { body, err := ioutil.ReadAll(r.Body) if err != nil { panic(err) } var level int if string(body) == "on" { level = 1 } else if string(body) == "off" { level = 0 } else { http.Error(w, "body must be 'on' or 'off'", http.StatusBadRequest) return } hwio.DigitalWrite(pins.OutLed, level) pins.LastOutLed = level http.Error(w, "", http.StatusAccepted) })) setStrike := func (level int) { hwio.DigitalWrite(pins.OutStrike, level) pins.LastOutStrike = level } m.Put("/strike", http.HandlerFunc(func (w http.ResponseWriter, r *http.Request) { level, err := booleanBody(w, r) if err != nil { panic(err) } setStrike(level) http.Error(w, "", http.StatusAccepted) })) m.Put("/strike/temporaryUnlock", http.HandlerFunc(func (w http.ResponseWriter, r *http.Request) { err := r.ParseForm() if err != nil { panic(err) } seconds, err2 := strconv.ParseFloat(string(r.Form["seconds"][0]), 32) if err2 != nil { http.Error(w, "seconds must be a float", http.StatusBadRequest) return } // This is not correctly reentrant. There should be a // stack of temporary effects that unpop correctly, // and status should show you any running effects. setStrike(1) go func() { time.Sleep(time.Duration(seconds * float64(time.Second))) setStrike(0) }() http.Error(w, "", http.StatusAccepted) })) m.Put("/speaker/beep", http.HandlerFunc(func (w http.ResponseWriter, r *http.Request) { // queue a beep http.Error(w, "", http.StatusAccepted) })) http.Handle("/", m) log.Printf("Listening on port 8081") err := http.ListenAndServe(":8081", nil) if err != nil { log.Fatal("ListenAndServe: ", err) } }