Mercurial > code > home > repos > homeauto
changeset 138:cc04b6af0477
start pilight server in go
Ignore-this: f10b5ce373b929bcedbe18b315f0abb9
author | drewp@bigasterisk.com |
---|---|
date | Sat, 12 Jul 2014 11:31:40 -0700 |
parents | 1952788e5299 |
children | 5b607e8d35d0 |
files | service/pilight/pilight.go service/pilight/readme service/pilight/static/index.html |
diffstat | 3 files changed, 217 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/service/pilight/pilight.go Sat Jul 12 11:31:40 2014 -0700 @@ -0,0 +1,118 @@ +package main + +import "github.com/go-martini/martini" +import "github.com/tarm/goserial" +import "log" +import "io" +import "net/http" +import "image/color" +import "color/hex" +import "strconv" +import "time" + +const ledCount = 3 + +type Board struct { + ser io.ReadWriteCloser + LedColors [ledCount]color.Color +} + +func OpenBoard(dev string) (*Board, error) { + c := &serial.Config{Name: dev, Baud: 115200} + ser, err := serial.OpenPort(c) + if err != nil { + return nil, err + } + log.Printf("wait for arduino to start up") + time.Sleep(2 * time.Second) + b := &Board{ser: ser} + for i := 0; i < ledCount; i++ { + b.LedColors[i] = color.RGBA{} + } + return b, err +} + +func (b *Board) Write(cmd byte, msg []byte) error { + head := make([]byte, 2) + head[0] = 0x60 + head[1] = cmd + _, err := b.ser.Write(head) + if err != nil { + return err + } + _, err = b.ser.Write(msg) + if err != nil { + return err + } + return err +} + +func (b *Board) UpdateLeds() error { + bytes := make([]byte, 9) + + for i := 0; i < ledCount; i++ { + r, g, b, _ := b.LedColors[i].RGBA() + bytes[i*3+0] = uint8(r) + bytes[i*3+1] = uint8(g) + bytes[i*3+2] = uint8(b) + } + return b.Write(0, bytes) +} + +func getBodyStringColor(req *http.Request) (c color.Color, err error) { + bytes := make([]byte, 1024) + n, err := req.Body.Read(bytes) + body := hex.Hex(string(bytes[:n])) + if err != nil { + return + } + r, g, b := hex.HexToRGB(body) + return color.RGBA{r, g, b, 0}, nil +} + +func main() { + board, err := OpenBoard("/dev/serial/by-id/usb-FTDI_FT232R_USB_UART_A9YLHR7R-if00-port0") + if err != nil { + log.Fatal(err) + } + + m := martini.Classic() + m.Martini.Use(martini.Static("static")) + m.Get("/", martini.Static("static", martini.StaticOptions{})) + m.Put("/led/:id", func(req *http.Request, params martini.Params) (int, string) { + color, err := getBodyStringColor(req) + if err != nil { + return 400, "" + } + which, err := strconv.Atoi(params["id"]) + if err != nil { + return 400, "" + } + + board.LedColors[which] = color + err = board.UpdateLeds() + if err != nil { + return 500, "" + } + + return 200, "ok" + }) + m.Get("/led", func() string { + return "['#ff0000', '#ff0000']" + }) + m.Put("/led", func(req *http.Request) (int, string) { + color, err := getBodyStringColor(req) + if err != nil { + return 400, "" + } + + for i := 0; i < ledCount; i++ { + board.LedColors[i] = color + } + err = board.UpdateLeds() + + return 200, "ok" + }) + log.Printf("serving") + m.Run() +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/service/pilight/readme Sat Jul 12 11:31:40 2014 -0700 @@ -0,0 +1,18 @@ + +GET / + info + +PUT /led/0 <- '#ff0000' + +PUT /led <- '#ff0000' sets all + +GET /led/0 -> '#ff0000' +GET /led -> ['#ff0000', '#ff0000'] json + +POST /image <- png; -> Location: /image/1 +PUT /image/1 <- new png +GET /image/1 -> png +PUT /animationMode <- {mode: 'continuous', image: '/image/1', pxPerSec: 30} +PUT /animationMode <- {mode: 'none'} +GET /animationMode -> last input json +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/service/pilight/static/index.html Sat Jul 12 11:31:40 2014 -0700 @@ -0,0 +1,81 @@ +<!doctype html> +<html> + <head> + <title>pilight</title> + <meta charset="utf-8" /> + <script src="//bigasterisk.com/lib/jquery-2.0.3.js"></script> + <script src="//bigasterisk.com/lib/platform/0.2.3/platform.js"></script> + <link rel="import" href="static/input-rgb/input-rgb.html"> + <style> + input-rgb { + border: 1px solid gray; + width: 300px; + } + </style> + </head> + <body> + + <polymer-element name="led-output" attributes="url color"> + <!-- calls PUT <url> with color string as the body, but also + avoids sending many repeated calls to url while the first one + is still in progress --> + <template> + {{status}} + </template> + <script>Polymer('led-output', { + created: function() { + this.pending = {}; // url: data + this.inflight = false; + }, + colorChanged: function() { + this.pending["led"] = this.color; + this.sendMore(); + }, + sendMore: function() { + if (this.inflight) { + return; + } + var urls = Object.keys(this.pending); + if (!urls.length) { + return; + } + var url = urls.pop(); + var data = this.pending[url]; + delete this.pending[url]; + + this.status = "Sending..."; + this.inflight = true; + $.ajax({ + type: "PUT", + url: url, + data: data, + success: function() { + this.status = ""; + }.bind(this), + error: function() { + this.status = "Send failed"; + }.bind(this), + complete: function() { + this.inflight = false; + this.sendMore(); + }.bind(this) + }); + } + }); + </script> + + </polymer-element> + + <polymer-element name="pilight-page" noscript> + <template> + LED0 color: + <input-rgb editable="true" hex="{{c1}}"></input-rgb> + <led-output which="led" color="{{c1}}"></led-output> + </template> + </polymer-element> + + <pilight-page></pilight-page> + + + </body> +</html>