Mercurial > code > home > repos > homeauto
changeset 498:0afe27203068
rm old golang service that ran on a pi connected to an arduino connected to RGB leds. includes some color picker using polymer
Ignore-this: ca47318f8bea6603ff3d584df19d5ca
author | drewp@bigasterisk.com |
---|---|
date | Sun, 21 Apr 2019 02:52:49 -0700 |
parents | e611f1486358 |
children | 3bbea09efce6 |
files | service/pilight/makefile service/pilight/pilight.go service/pilight/readme service/pilight/src/color/hex/colorhex.go service/pilight/static/big-picker.html service/pilight/static/color.js service/pilight/static/index.html |
diffstat | 7 files changed, 0 insertions(+), 1363 deletions(-) [+] |
line wrap: on
line diff
--- a/service/pilight/makefile Sun Apr 21 02:48:58 2019 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,18 +0,0 @@ -GOPATH=$(shell pwd) -export GOPATH -build: deps - go build pilight.go - -deps: src/github.com/tarm/goserial src/github.com/go-martini/martini - -src/github.com/tarm/goserial: - go get github.com/tarm/goserial -src/github.com/go-martini/martini: - go get github.com/go-martini/martini - -setup: - ln -s . public - -build-to-pi: deps - GOBIN=bin-pi GOARCH=arm go install pilight.go - rsync -a bin-pi/pilight pi@192.168.1.157:projects/homeauto/service/pilight/bin/
--- a/service/pilight/pilight.go Sun Apr 21 02:48:58 2019 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,195 +0,0 @@ -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" -import "net/textproto" -import "bufio" -import "errors" -import "encoding/json" - -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 (b *Board) ReadDht() (string, error) { - for try := 0; try < 5; try++ { - err := b.Write(0x2, make([]byte, 0)) - if err != nil { - continue - } - - reader := textproto.NewReader(bufio.NewReader(b.ser)) - json, err := reader.ReadLine() - if err != nil { - continue - } - return json, nil - } - return "", errors.New("failed after all retries") -} - - -func (b *Board) ReadLeds() (colors []color.Color, err error) { - err = b.Write(0x3, make([]byte, 0)) - if err != nil { - return - } - reader := textproto.NewReader(bufio.NewReader(b.ser)) - line, err := reader.ReadLineBytes() - if err != nil { - return - } - - type LedsMessage struct { - Leds []string - } - var ret LedsMessage - err = json.Unmarshal(line, &ret) - if err != nil { - return - } - - colors = make([]color.Color, len(ret.Leds)) - for i, c := range ret.Leds { - r, g, b := hex.HexToRGB(hex.Hex(c)) - colors[i] = color.RGBA{r, g, b, 0} - } - - return colors, nil -} - -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() (int, string) { - - colors, err := board.ReadLeds() - if err != nil { - return 500, "" - } - hexColors := make([]hex.Hex, len(colors)) - for i, c := range colors { - // hex.HexModel.Convert(c) seems like the - // right call, but fails because it returns - // Color not string - r, g, b, _ := c.RGBA() - hexColors[i] = hex.RGBToHex(uint8(r), uint8(g), uint8(b)) - } - - // content-type json - j, err := json.Marshal(hexColors) - if err != nil { - return 500, "" - } - return 200, string(j) - }) - 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" - }) - m.Get("/dht", func() (int, string) { - json, err := board.ReadDht() - if err != nil { - return 500, "" - } - return 200, json - }) - log.Printf("serving") - m.Run() -}
--- a/service/pilight/readme Sun Apr 21 02:48:58 2019 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,18 +0,0 @@ - -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 -
--- a/service/pilight/src/color/hex/colorhex.go Sun Apr 21 02:48:58 2019 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,58 +0,0 @@ -// From https://github.com/zond/wildlife/blob/master/code.google.com/p/gorilla/color/hex.go - -// Copyright 2012 The Gorilla Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package hex - -import ( - "fmt" - "image/color" - "strconv" -) - -// HexModel converts any Color to an Hex color. -var HexModel = color.ModelFunc(hexModel) - -// Hex represents an RGB color in hexadecimal format. -// -// The length must be 3 or 6 characters, preceded or not by a '#'. -type Hex string - -// RGBA returns the alpha-premultiplied red, green, blue and alpha values -// for the Hex. -func (c Hex) RGBA() (uint32, uint32, uint32, uint32) { - r, g, b := HexToRGB(c) - return uint32(r) * 0x101, uint32(g) * 0x101, uint32(b) * 0x101, 0xffff -} - -// hexModel converts a Color to Hex. -func hexModel(c color.Color) color.Color { - if _, ok := c.(Hex); ok { - return c - } - r, g, b, _ := c.RGBA() - return RGBToHex(uint8(r>>8), uint8(g>>8), uint8(b>>8)) -} - -// RGBToHex converts an RGB triple to an Hex string. -func RGBToHex(r, g, b uint8) Hex { - return Hex(fmt.Sprintf("#%02X%02X%02X", r, g, b)) -} - -// HexToRGB converts an Hex string to a RGB triple. -func HexToRGB(h Hex) (uint8, uint8, uint8) { - if len(h) > 0 && h[0] == '#' { - h = h[1:] - } - if len(h) == 3 { - h = h[:1] + h[:1] + h[1:2] + h[1:2] + h[2:] + h[2:] - } - if len(h) == 6 { - if rgb, err := strconv.ParseUint(string(h), 16, 32); err == nil { - return uint8(rgb >> 16), uint8((rgb >> 8) & 0xFF), uint8(rgb & 0xFF) - } - } - return 0, 0, 0 -}
--- a/service/pilight/static/big-picker.html Sun Apr 21 02:48:58 2019 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,94 +0,0 @@ -<polymer-element name="big-picker" attributes="hex"> - <template> - <style> - .pot { - width: 50px; - height: 50px; - border-radius: 50%; - box-shadow: 3px 2px 10px black; - border: 2px solid white; - margin: 10px; - position: absolute; - } - input[type=range] { - -webkit-appearance: slider-vertical; - } - #wide { - display: flex; - } - #samples { - outline: 1px solid gray; - width: 300px; - height: 300px; - position: relative; - } - #swatch { - position: absolute; - left: 110px; - top: 110px; - width: 60px; - height: 60px; - } - - #lightness { - display: flex; - outline: 1px gray solid; - background: linear-gradient(to bottom, #ffffff 0%,#0e0e0e 100%); - width: 50px; - } - </style> - - <div id="wide"> - <div id="samples"> - <template repeat="{{c in potColors}}"> - <div class="pot" style="background: {{c}}" on-click="{{setColor}}"></div> - </template> - <input id="swatch" type="color" id="picker" value="{{hex}}" orient="vertical"> - </div> - - <div id="lightness"> - <input type="range" min="0" max="1" step=".01" value="{{lightness}}"> - </div> - </div> - </template> - - <script src="color.js"></script> - <script type="text/javascript"> - var Color = net.brehaut.Color; - Polymer('big-picker', { - hex: '#ffffff', - ready: function() { - this.lightness = .5; - this.potColors = ['hsl(20, 100%, 50%)', - 'hsl(60, 100%, 50%)', - 'hsl(100, 100%, 50%)', - 'hsl(140, 100%, 50%)', - 'hsl(180, 100%, 50%)', - 'hsl(220, 100%, 50%)', - 'hsl(260, 100%, 50%)', - 'hsl(300, 100%, 50%)', - 'hsl(340, 100%, 50%)', - '#888888']; - }, - domReady: function() { - var pots = this.$.samples.getElementsByClassName("pot"); - $.each(pots, function (i, elem) { - var frac = i / pots.length; - elem.style.left = (100 + 100 * Math.sin(frac * 2 * Math.PI)) + "px"; - elem.style.top = (100 + 100 * Math.cos(frac * 2 * Math.PI)) + "px"; - }); - }, - setColor: function(e) { - var c = Color(e.target.templateInstance.model.c).setLightness(this.lightness); - this.hex = c.toString(); - }, - hexChanged: function() { - this.lightness = Color(this.hex).getLightness(); - }, - lightnessChanged: function() { - var c = Color(this.hex).setLightness(this.lightness); - this.hex = c.toString(); - } - }); - </script> -</polymer-element>
--- a/service/pilight/static/color.js Sun Apr 21 02:48:58 2019 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,840 +0,0 @@ -// Copyright (c) 2008-2013, Andrew Brehaut, Tim Baumann, Matt Wilson, -// Simon Heimler, Michel Vielmetter -// -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. - -// color.js - version 1.0.1 -// -// HSV <-> RGB code based on code from http://www.cs.rit.edu/~ncs/color/t_convert.html -// object function created by Douglas Crockford. -// Color scheme degrees taken from the colorjack.com colorpicker -// -// HSL support kindly provided by Tim Baumann - http://github.com/timjb - -// create namespaces -/*global net */ -if ("undefined" == typeof net) { var net = {}; } -if (!net.brehaut) { net.brehaut = {}; } - -// this module function is called with net.brehaut as 'this' -(function ( ) { - "use strict"; - // Constants - - // css_colors maps color names onto their hex values - // these names are defined by W3C - var css_colors = {aliceblue:'#F0F8FF',antiquewhite:'#FAEBD7',aqua:'#00FFFF',aquamarine:'#7FFFD4',azure:'#F0FFFF',beige:'#F5F5DC',bisque:'#FFE4C4',black:'#000000',blanchedalmond:'#FFEBCD',blue:'#0000FF',blueviolet:'#8A2BE2',brown:'#A52A2A',burlywood:'#DEB887',cadetblue:'#5F9EA0',chartreuse:'#7FFF00',chocolate:'#D2691E',coral:'#FF7F50',cornflowerblue:'#6495ED',cornsilk:'#FFF8DC',crimson:'#DC143C',cyan:'#00FFFF',darkblue:'#00008B',darkcyan:'#008B8B',darkgoldenrod:'#B8860B',darkgray:'#A9A9A9',darkgrey:'#A9A9A9',darkgreen:'#006400',darkkhaki:'#BDB76B',darkmagenta:'#8B008B',darkolivegreen:'#556B2F',darkorange:'#FF8C00',darkorchid:'#9932CC',darkred:'#8B0000',darksalmon:'#E9967A',darkseagreen:'#8FBC8F',darkslateblue:'#483D8B',darkslategray:'#2F4F4F',darkslategrey:'#2F4F4F',darkturquoise:'#00CED1',darkviolet:'#9400D3',deeppink:'#FF1493',deepskyblue:'#00BFFF',dimgray:'#696969',dimgrey:'#696969',dodgerblue:'#1E90FF',firebrick:'#B22222',floralwhite:'#FFFAF0',forestgreen:'#228B22',fuchsia:'#FF00FF',gainsboro:'#DCDCDC',ghostwhite:'#F8F8FF',gold:'#FFD700',goldenrod:'#DAA520',gray:'#808080',grey:'#808080',green:'#008000',greenyellow:'#ADFF2F',honeydew:'#F0FFF0',hotpink:'#FF69B4',indianred:'#CD5C5C',indigo:'#4B0082',ivory:'#FFFFF0',khaki:'#F0E68C',lavender:'#E6E6FA',lavenderblush:'#FFF0F5',lawngreen:'#7CFC00',lemonchiffon:'#FFFACD',lightblue:'#ADD8E6',lightcoral:'#F08080',lightcyan:'#E0FFFF',lightgoldenrodyellow:'#FAFAD2',lightgray:'#D3D3D3',lightgrey:'#D3D3D3',lightgreen:'#90EE90',lightpink:'#FFB6C1',lightsalmon:'#FFA07A',lightseagreen:'#20B2AA',lightskyblue:'#87CEFA',lightslategray:'#778899',lightslategrey:'#778899',lightsteelblue:'#B0C4DE',lightyellow:'#FFFFE0',lime:'#00FF00',limegreen:'#32CD32',linen:'#FAF0E6',magenta:'#FF00FF',maroon:'#800000',mediumaquamarine:'#66CDAA',mediumblue:'#0000CD',mediumorchid:'#BA55D3',mediumpurple:'#9370D8',mediumseagreen:'#3CB371',mediumslateblue:'#7B68EE',mediumspringgreen:'#00FA9A',mediumturquoise:'#48D1CC',mediumvioletred:'#C71585',midnightblue:'#191970',mintcream:'#F5FFFA',mistyrose:'#FFE4E1',moccasin:'#FFE4B5',navajowhite:'#FFDEAD',navy:'#000080',oldlace:'#FDF5E6',olive:'#808000',olivedrab:'#6B8E23',orange:'#FFA500',orangered:'#FF4500',orchid:'#DA70D6',palegoldenrod:'#EEE8AA',palegreen:'#98FB98',paleturquoise:'#AFEEEE',palevioletred:'#D87093',papayawhip:'#FFEFD5',peachpuff:'#FFDAB9',peru:'#CD853F',pink:'#FFC0CB',plum:'#DDA0DD',powderblue:'#B0E0E6',purple:'#800080',rebeccapurple:'#663399',red:'#FF0000',rosybrown:'#BC8F8F',royalblue:'#4169E1',saddlebrown:'#8B4513',salmon:'#FA8072',sandybrown:'#F4A460',seagreen:'#2E8B57',seashell:'#FFF5EE',sienna:'#A0522D',silver:'#C0C0C0',skyblue:'#87CEEB',slateblue:'#6A5ACD',slategray:'#708090',slategrey:'#708090',snow:'#FFFAFA',springgreen:'#00FF7F',steelblue:'#4682B4',tan:'#D2B48C',teal:'#008080',thistle:'#D8BFD8',tomato:'#FF6347',turquoise:'#40E0D0',violet:'#EE82EE',wheat:'#F5DEB3',white:'#FFFFFF',whitesmoke:'#F5F5F5',yellow:'#FFFF00',yellowgreen:'#9ACD32"'}; - - // CSS value regexes, according to http://www.w3.org/TR/css3-values/ - var css_integer = '(?:\\+|-)?\\d+'; - var css_float = '(?:\\+|-)?\\d*\\.\\d+'; - var css_number = '(?:' + css_integer + ')|(?:' + css_float + ')'; - css_integer = '(' + css_integer + ')'; - css_float = '(' + css_float + ')'; - css_number = '(' + css_number + ')'; - var css_percentage = css_number + '%'; - var css_whitespace = '\\s*?'; - - // http://www.w3.org/TR/2003/CR-css3-color-20030514/ - var hsl_hsla_regex = new RegExp([ - '^hsl(a?)\\(', css_number, ',', css_percentage, ',', css_percentage, '(,(', css_number, '))?\\)$' - ].join(css_whitespace) ); - var rgb_rgba_integer_regex = new RegExp([ - '^rgb(a?)\\(', css_integer, ',', css_integer, ',', css_integer, '(,(', css_number, '))?\\)$' - ].join(css_whitespace) ); - var rgb_rgba_percentage_regex = new RegExp([ - '^rgb(a?)\\(', css_percentage, ',', css_percentage, ',', css_percentage, '(,(', css_number, '))?\\)$' - ].join(css_whitespace) ); - - // Package wide variables - - // becomes the top level prototype object - var color; - - /* registered_models contains the template objects for all the - * models that have been registered for the color class. - */ - var registered_models = []; - - - /* factories contains methods to create new instance of - * different color models that have been registered. - */ - var factories = {}; - - // Utility functions - - /* object is Douglas Crockfords object function for prototypal - * inheritance. - */ - if (!this.object) { - this.object = function (o) { - function F () { } - F.prototype = o; - return new F(); - }; - } - var object = this.object; - - /* takes a value, converts to string if need be, then pads it - * to a minimum length. - */ - function pad ( val, len ) { - val = val.toString(); - var padded = []; - - for (var i = 0, j = Math.max( len - val.length, 0); i < j; i++) { - padded.push('0'); - } - - padded.push(val); - return padded.join(''); - } - - - /* takes a string and returns a new string with the first letter - * capitalised - */ - function capitalise ( s ) { - return s.slice(0,1).toUpperCase() + s.slice(1); - } - - /* removes leading and trailing whitespace - */ - function trim ( str ) { - return str.replace(/^\s+|\s+$/g, ''); - } - - /* used to apply a method to object non-destructively by - * cloning the object and then apply the method to that - * new object - */ - function cloneOnApply( meth ) { - return function ( ) { - var cloned = this.clone(); - meth.apply(cloned, arguments); - return cloned; - }; - } - - - /* registerModel is used to add additional representations - * to the color code, and extend the color API with the new - * operatiosn that model provides. see before for examples - */ - function registerModel( name, model ) { - var proto = object(color); - var fields = []; // used for cloning and generating accessors - - var to_meth = 'to'+ capitalise(name); - - function convertAndApply( meth ) { - return function ( ) { - return meth.apply(this[to_meth](), arguments); - }; - } - - for (var key in model) if (model.hasOwnProperty(key)) { - proto[key] = model[key]; - var prop = proto[key]; - - if (key.slice(0,1) == '_') { continue; } - if (!(key in color) && "function" == typeof prop) { - // the method found on this object is a) public and b) not - // currently supported by the color object. Create an impl that - // calls the toModel function and passes that new object - // onto the correct method with the args. - color[key] = convertAndApply(prop); - } - else if ("function" != typeof prop) { - // we have found a public property. create accessor methods - // and bind them up correctly - fields.push(key); - var getter = 'get'+capitalise(key); - var setter = 'set'+capitalise(key); - - color[getter] = convertAndApply( - proto[getter] = (function ( key ) { - return function ( ) { - return this[key]; - }; - })( key ) - ); - - color[setter] = convertAndApply( - proto[setter] = (function ( key ) { - return function ( val ) { - var cloned = this.clone(); - cloned[key] = val; - return cloned; - }; - })( key ) - ); - } - } // end of for over model - - // a method to create a new object - largely so prototype chains dont - // get insane. This uses an unrolled 'object' so that F is cached - // for later use. this is approx a 25% speed improvement - function F () { } - F.prototype = proto; - function factory ( ) { - return new F(); - } - factories[name] = factory; - - proto.clone = function () { - var cloned = factory(); - for (var i = 0, j = fields.length; i < j; i++) { - var key = fields[i]; - cloned[key] = this[key]; - } - return cloned; - }; - - color[to_meth] = function ( ) { - return factory(); - }; - - registered_models.push(proto); - - return proto; - }// end of registerModel - - // Template Objects - - /* color is the root object in the color hierarchy. It starts - * life as a very simple object, but as color models are - * registered it has methods programmatically added to manage - * conversions as needed. - */ - color = { - /* fromObject takes an argument and delegates to the internal - * color models to try to create a new instance. - */ - fromObject: function ( o ) { - if (!o) { - return object(color); - } - - for (var i = 0, j = registered_models.length; i < j; i++) { - var nu = registered_models[i].fromObject(o); - if (nu) { - return nu; - } - } - - return object(color); - }, - - toString: function ( ) { - return this.toCSS(); - } - }; - - var transparent = null; // defined with an RGB later. - - /* RGB is the red green blue model. This definition is converted - * to a template object by registerModel. - */ - registerModel('RGB', { - red: 0, - green: 0, - blue: 0, - alpha: 0, - - /* getLuminance returns a value between 0 and 1, this is the - * luminance calcuated according to - * http://www.poynton.com/notes/colour_and_gamma/ColorFAQ.html#RTFToC9 - */ - getLuminance: function ( ) { - return (this.red * 0.2126) + (this.green * 0.7152) + (this.blue * 0.0722); - }, - - /* does an alpha based blend of color onto this. alpha is the - * amount of 'color' to use. (0 to 1) - */ - blend: function ( color , alpha ) { - color = color.toRGB(); - alpha = Math.min(Math.max(alpha, 0), 1); - var rgb = this.clone(); - - rgb.red = (rgb.red * (1 - alpha)) + (color.red * alpha); - rgb.green = (rgb.green * (1 - alpha)) + (color.green * alpha); - rgb.blue = (rgb.blue * (1 - alpha)) + (color.blue * alpha); - rgb.alpha = (rgb.alpha * (1 - alpha)) + (color.alpha * alpha); - - return rgb; - }, - - /* fromObject attempts to convert an object o to and RGB - * instance. This accepts an object with red, green and blue - * members or a string. If the string is a known CSS color name - * or a hexdecimal string it will accept it. - */ - fromObject: function ( o ) { - if (o instanceof Array) { - return this._fromRGBArray ( o ); - } - if ("string" == typeof o) { - return this._fromCSS( trim( o ) ); - } - if (o.hasOwnProperty('red') && - o.hasOwnProperty('green') && - o.hasOwnProperty('blue')) { - return this._fromRGB ( o ); - } - // nothing matchs, not an RGB object - }, - - _stringParsers: [ - // CSS RGB(A) literal: - function ( css ) { - css = trim(css); - - var withInteger = match(rgb_rgba_integer_regex, 255); - if(withInteger) { - return withInteger; - } - return match(rgb_rgba_percentage_regex, 100); - - function match(regex, max_value) { - var colorGroups = css.match( regex ); - - // If there is an "a" after "rgb", there must be a fourth parameter and the other way round - if (!colorGroups || (!!colorGroups[1] + !!colorGroups[5] === 1)) { - return null; - } - - var rgb = factories.RGB(); - rgb.red = Math.min(1, Math.max(0, colorGroups[2] / max_value)); - rgb.green = Math.min(1, Math.max(0, colorGroups[3] / max_value)); - rgb.blue = Math.min(1, Math.max(0, colorGroups[4] / max_value)); - rgb.alpha = !!colorGroups[5] ? Math.min(Math.max(parseFloat(colorGroups[6]), 0), 1) : 1; - - return rgb; - } - }, - - function ( css ) { - var lower = css.toLowerCase(); - if (lower in css_colors) { - css = css_colors[lower]; - } - - if (!css.match(/^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/)) { - return; - } - - css = css.replace(/^#/,''); - - var bytes = css.length / 3; - - var max = Math.pow(16, bytes) - 1; - - var rgb = factories.RGB(); - rgb.red = parseInt(css.slice(0, bytes), 16) / max; - rgb.green = parseInt(css.slice(bytes * 1,bytes * 2), 16) / max; - rgb.blue = parseInt(css.slice(bytes * 2), 16) / max; - rgb.alpha = 1; - return rgb; - }, - - function ( css ) { - if (css.toLowerCase() !== 'transparent') return; - - return transparent; - } - ], - - _fromCSS: function ( css ) { - var color = null; - for (var i = 0, j = this._stringParsers.length; i < j; i++) { - color = this._stringParsers[i](css); - if (color) return color; - } - }, - - _fromRGB: function ( RGB ) { - var newRGB = factories.RGB(); - - newRGB.red = RGB.red; - newRGB.green = RGB.green; - newRGB.blue = RGB.blue; - newRGB.alpha = RGB.hasOwnProperty('alpha') ? RGB.alpha : 1; - - return newRGB; - }, - - _fromRGBArray: function ( RGB ) { - var newRGB = factories.RGB(); - - newRGB.red = Math.max(0, Math.min(1, RGB[0] / 255)); - newRGB.green = Math.max(0, Math.min(1, RGB[1] / 255)); - newRGB.blue = Math.max(0, Math.min(1, RGB[2] / 255)); - newRGB.alpha = RGB[3] !== undefined ? Math.max(0, Math.min(1, RGB[3])) : 1; - - return newRGB; - }, - - // convert to a CSS string. defaults to two bytes a value - toCSSHex: function ( bytes ) { - bytes = bytes || 2; - - var max = Math.pow(16, bytes) - 1; - var css = [ - "#", - pad ( Math.round(this.red * max).toString( 16 ).toUpperCase(), bytes ), - pad ( Math.round(this.green * max).toString( 16 ).toUpperCase(), bytes ), - pad ( Math.round(this.blue * max).toString( 16 ).toUpperCase(), bytes ) - ]; - - return css.join(''); - }, - - toCSS: function ( bytes ) { - if (this.alpha === 1) return this.toCSSHex(bytes); - - var max = 255; - - var components = [ - 'rgba(', - Math.max(0, Math.min(max, Math.round(this.red * max))), ',', - Math.max(0, Math.min(max, Math.round(this.green * max))), ',', - Math.max(0, Math.min(max, Math.round(this.blue * max))), ',', - Math.max(0, Math.min(1, this.alpha)), - ')' - ]; - - return components.join(''); - }, - - toHSV: function ( ) { - var hsv = factories.HSV(); - var min, max, delta; - - min = Math.min(this.red, this.green, this.blue); - max = Math.max(this.red, this.green, this.blue); - hsv.value = max; // v - - delta = max - min; - - if( delta == 0 ) { // white, grey, black - hsv.hue = hsv.saturation = 0; - } - else { // chroma - hsv.saturation = delta / max; - - if( this.red == max ) { - hsv.hue = ( this.green - this.blue ) / delta; // between yellow & magenta - } - else if( this.green == max ) { - hsv.hue = 2 + ( this.blue - this.red ) / delta; // between cyan & yellow - } - else { - hsv.hue = 4 + ( this.red - this.green ) / delta; // between magenta & cyan - } - - hsv.hue = ((hsv.hue * 60) + 360) % 360; // degrees - } - - hsv.alpha = this.alpha; - - return hsv; - }, - toHSL: function ( ) { - return this.toHSV().toHSL(); - }, - - toRGB: function ( ) { - return this.clone(); - } - }); - - transparent = color.fromObject({red: 0, blue: 0, green: 0, alpha: 0}); - - - /* Like RGB above, this object describes what will become the HSV - * template object. This model handles hue, saturation and value. - * hue is the number of degrees around the color wheel, saturation - * describes how much color their is and value is the brightness. - */ - registerModel('HSV', { - hue: 0, - saturation: 0, - value: 1, - alpha: 1, - - shiftHue: cloneOnApply(function ( degrees ) { - var hue = (this.hue + degrees) % 360; - if (hue < 0) { - hue = (360 + hue) % 360; - } - - this.hue = hue; - }), - - devalueByAmount: cloneOnApply(function ( val ) { - this.value = Math.min(1, Math.max(this.value - val, 0)); - }), - - devalueByRatio: cloneOnApply(function ( val ) { - this.value = Math.min(1, Math.max(this.value * (1 - val), 0)); - }), - - valueByAmount: cloneOnApply(function ( val ) { - this.value = Math.min(1, Math.max(this.value + val, 0)); - }), - - valueByRatio: cloneOnApply(function ( val ) { - this.value = Math.min(1, Math.max(this.value * (1 + val), 0)); - }), - - desaturateByAmount: cloneOnApply(function ( val ) { - this.saturation = Math.min(1, Math.max(this.saturation - val, 0)); - }), - - desaturateByRatio: cloneOnApply(function ( val ) { - this.saturation = Math.min(1, Math.max(this.saturation * (1 - val), 0)); - }), - - saturateByAmount: cloneOnApply(function ( val ) { - this.saturation = Math.min(1, Math.max(this.saturation + val, 0)); - }), - - saturateByRatio: cloneOnApply(function ( val ) { - this.saturation = Math.min(1, Math.max(this.saturation * (1 + val), 0)); - }), - - schemeFromDegrees: function ( degrees ) { - var newColors = []; - for (var i = 0, j = degrees.length; i < j; i++) { - var col = this.clone(); - col.hue = (this.hue + degrees[i]) % 360; - newColors.push(col); - } - return newColors; - }, - - complementaryScheme: function ( ) { - return this.schemeFromDegrees([0,180]); - }, - - splitComplementaryScheme: function ( ) { - return this.schemeFromDegrees([0,150,320]); - }, - - splitComplementaryCWScheme: function ( ) { - return this.schemeFromDegrees([0,150,300]); - }, - - splitComplementaryCCWScheme: function ( ) { - return this.schemeFromDegrees([0,60,210]); - }, - - triadicScheme: function ( ) { - return this.schemeFromDegrees([0,120,240]); - }, - - clashScheme: function ( ) { - return this.schemeFromDegrees([0,90,270]); - }, - - tetradicScheme: function ( ) { - return this.schemeFromDegrees([0,90,180,270]); - }, - - fourToneCWScheme: function ( ) { - return this.schemeFromDegrees([0,60,180,240]); - }, - - fourToneCCWScheme: function ( ) { - return this.schemeFromDegrees([0,120,180,300]); - }, - - fiveToneAScheme: function ( ) { - return this.schemeFromDegrees([0,115,155,205,245]); - }, - - fiveToneBScheme: function ( ) { - return this.schemeFromDegrees([0,40,90,130,245]); - }, - - fiveToneCScheme: function ( ) { - return this.schemeFromDegrees([0,50,90,205,320]); - }, - - fiveToneDScheme: function ( ) { - return this.schemeFromDegrees([0,40,155,270,310]); - }, - - fiveToneEScheme: function ( ) { - return this.schemeFromDegrees([0,115,230,270,320]); - }, - - sixToneCWScheme: function ( ) { - return this.schemeFromDegrees([0,30,120,150,240,270]); - }, - - sixToneCCWScheme: function ( ) { - return this.schemeFromDegrees([0,90,120,210,240,330]); - }, - - neutralScheme: function ( ) { - return this.schemeFromDegrees([0,15,30,45,60,75]); - }, - - analogousScheme: function ( ) { - return this.schemeFromDegrees([0,30,60,90,120,150]); - }, - - fromObject: function ( o ) { - if (o.hasOwnProperty('hue') && - o.hasOwnProperty('saturation') && - o.hasOwnProperty('value')) { - var hsv = factories.HSV(); - - hsv.hue = o.hue; - hsv.saturation = o.saturation; - hsv.value = o.value; - hsv.alpha = o.hasOwnProperty('alpha') ? o.alpha : 1; - - return hsv; - } - // nothing matches, not an HSV object - return null; - }, - - _normalise: function ( ) { - this.hue %= 360; - this.saturation = Math.min(Math.max(0, this.saturation), 1); - this.value = Math.min(Math.max(0, this.value)); - this.alpha = Math.min(1, Math.max(0, this.alpha)); - }, - - toRGB: function ( ) { - this._normalise(); - - var rgb = factories.RGB(); - var i; - var f, p, q, t; - - if( this.saturation === 0 ) { - // achromatic (grey) - rgb.red = this.value; - rgb.green = this.value; - rgb.blue = this.value; - rgb.alpha = this.alpha; - return rgb; - } - - var h = this.hue / 60; // sector 0 to 5 - i = Math.floor( h ); - f = h - i; // factorial part of h - p = this.value * ( 1 - this.saturation ); - q = this.value * ( 1 - this.saturation * f ); - t = this.value * ( 1 - this.saturation * ( 1 - f ) ); - - switch( i ) { - case 0: - rgb.red = this.value; - rgb.green = t; - rgb.blue = p; - break; - case 1: - rgb.red = q; - rgb.green = this.value; - rgb.blue = p; - break; - case 2: - rgb.red = p; - rgb.green = this.value; - rgb.blue = t; - break; - case 3: - rgb.red = p; - rgb.green = q; - rgb.blue = this.value; - break; - case 4: - rgb.red = t; - rgb.green = p; - rgb.blue = this.value; - break; - default: // case 5: - rgb.red = this.value; - rgb.green = p; - rgb.blue = q; - break; - } - - rgb.alpha = this.alpha; - - return rgb; - }, - toHSL: function() { - this._normalise(); - - var hsl = factories.HSL(); - - hsl.hue = this.hue; - var l = (2 - this.saturation) * this.value, - s = this.saturation * this.value; - if(l && 2 - l) { - s /= (l <= 1) ? l : 2 - l; - } - l /= 2; - hsl.saturation = s; - hsl.lightness = l; - hsl.alpha = this.alpha; - - return hsl; - }, - - toHSV: function ( ) { - return this.clone(); - } - }); - - registerModel('HSL', { - hue: 0, - saturation: 0, - lightness: 0, - alpha: 1, - - darkenByAmount: cloneOnApply(function ( val ) { - this.lightness = Math.min(1, Math.max(this.lightness - val, 0)); - }), - - darkenByRatio: cloneOnApply(function ( val ) { - this.lightness = Math.min(1, Math.max(this.lightness * (1 - val), 0)); - }), - - lightenByAmount: cloneOnApply(function ( val ) { - this.lightness = Math.min(1, Math.max(this.lightness + val, 0)); - }), - - lightenByRatio: cloneOnApply(function ( val ) { - this.lightness = Math.min(1, Math.max(this.lightness * (1 + val), 0)); - }), - - fromObject: function ( o ) { - if ("string" == typeof o) { - return this._fromCSS( o ); - } - if (o.hasOwnProperty('hue') && - o.hasOwnProperty('saturation') && - o.hasOwnProperty('lightness')) { - return this._fromHSL ( o ); - } - // nothing matchs, not an RGB object - }, - - _fromCSS: function ( css ) { - var colorGroups = trim( css ).match( hsl_hsla_regex ); - - // if there is an "a" after "hsl", there must be a fourth parameter and the other way round - if (!colorGroups || (!!colorGroups[1] + !!colorGroups[5] === 1)) { - return null; - } - - var hsl = factories.HSL(); - hsl.hue = (colorGroups[2] % 360 + 360) % 360; - hsl.saturation = Math.max(0, Math.min(parseInt(colorGroups[3], 10) / 100, 1)); - hsl.lightness = Math.max(0, Math.min(parseInt(colorGroups[4], 10) / 100, 1)); - hsl.alpha = !!colorGroups[5] ? Math.max(0, Math.min(1, parseFloat(colorGroups[6]))) : 1; - - return hsl; - }, - - _fromHSL: function ( HSL ) { - var newHSL = factories.HSL(); - - newHSL.hue = HSL.hue; - newHSL.saturation = HSL.saturation; - newHSL.lightness = HSL.lightness; - - newHSL.alpha = HSL.hasOwnProperty('alpha') ? HSL.alpha : 1; - - return newHSL; - }, - - _normalise: function ( ) { - this.hue = (this.hue % 360 + 360) % 360; - this.saturation = Math.min(Math.max(0, this.saturation), 1); - this.lightness = Math.min(Math.max(0, this.lightness)); - this.alpha = Math.min(1, Math.max(0, this.alpha)); - }, - - toHSL: function() { - return this.clone(); - }, - toHSV: function() { - this._normalise(); - - var hsv = factories.HSV(); - - // http://ariya.blogspot.com/2008/07/converting-between-hsl-and-hsv.html - hsv.hue = this.hue; // H - var l = 2 * this.lightness, - s = this.saturation * ((l <= 1) ? l : 2 - l); - hsv.value = (l + s) / 2; // V - hsv.saturation = ((2 * s) / (l + s)) || 0; // S - hsv.alpha = this.alpha; - - return hsv; - }, - toRGB: function() { - return this.toHSV().toRGB(); - } - }); - - // Package specific exports - - /* the Color function is a factory for new color objects. - */ - function Color( o ) { - return color.fromObject( o ); - } - Color.isValid = function( str ) { - var key, c = Color( str ); - - var length = 0; - for(key in c) { - if(c.hasOwnProperty(key)) { - length++; - } - } - - return length > 0; - }; - net.brehaut.Color = Color; -}).call(net.brehaut); - -/* Export to CommonJS -*/ -var module; -if(module) { - module.exports.Color = net.brehaut.Color; -}
--- a/service/pilight/static/index.html Sun Apr 21 02:48:58 2019 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,140 +0,0 @@ -<!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> - <script src="//bigasterisk.com/lib/polymer/0.2.3/polymer.js"></script> - <link rel="import" href="static/big-picker.html"> - <style> - body { - background: #5c5c5c; - color: #E2E2E2; - } - </style> - </head> - <body> - - <polymer-element name="led-output" attributes="url color"> - <!-- - First fetches the first led color and writes it on the color - attribute, then whenever color changes, 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; - this.enableWrites = false; - - var retryFetch = function (triesLeft) { - if (triesLeft < 1) { - return; - } - $.ajax({ - type: "GET", - url: "led", - dataType: "json", - success: function(result) { - if (!result.length) { - setTimeout(function() { - retryFetch(triesLeft - 1); - }.bind(this), 100); - return; - } - this.color = result[0]; - this.enableWrites = true; - }.bind(this) - }); - }.bind(this); - retryFetch(5); - }, - colorChanged: function() { - if (!this.enableWrites) { - return; - } - 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> - LED color: - <big-picker hex="{{c1}}"></big-picker> - <led-output which="led" color="{{c1}}"></led-output> - </template> - </polymer-element> - - <pilight-page></pilight-page> - - <div> - DHT: <span id="dht"></span> - <div id="temperature" style="background: #034c4d"></div> - <div id="humidity" style="background: #663d66"></div> - </div> - - <script> - $(function() { - function update() { - $.getJSON("dht", function(result) { - result['tempF'] = 1.8 * result['temperature'] + 32; - result['time'] = new Date().toLocaleString(); - $("#dht").text(JSON.stringify(result)); - $("#temperature") - .text(result['tempF'] + " deg F") - .css('width', result['temperature'] * 10); - $("#humidity") - .text(result['humidity'] + " humidity") - .css('width', result['humidity'] * 10); - }); - } - - function loop() { - update(); - setTimeout(function() { - requestAnimationFrame(loop); - }, 2000); - } - $.getJSON("dht", loop); - }); - </script> - </body> -</html>