lume/color.go

215 lines
4.4 KiB
Go
Raw Normal View History

2020-02-29 22:00:21 +00:00
package lifx
import (
2020-03-07 02:55:31 +00:00
"encoding/json"
2020-03-08 18:47:01 +00:00
"errors"
2020-02-29 22:00:21 +00:00
"fmt"
2020-03-07 02:55:31 +00:00
"net/http"
2020-02-29 22:00:21 +00:00
"strings"
)
type (
Color interface {
ColorString() string
}
)
type (
RGBColor struct {
R, G, B uint8
}
HSBKColor struct {
2020-03-08 18:47:01 +00:00
H *float32 `json:"hue"`
S *float32 `json:"saturation"`
B *float32 `json:"brightness"`
K *int16 `json:"kelvin"`
2020-02-29 22:00:21 +00:00
}
2020-02-29 22:09:05 +00:00
NamedColor string
2020-02-29 22:00:21 +00:00
)
2020-03-22 16:31:10 +00:00
const (
2020-03-22 19:41:54 +00:00
KelvinCandlelight = 1500
KelvinSunset = 2000
KelvinUltraWarm = 2500
KelvinIncandescent = 2700
KelvinWarm = 3000
KelvinCool = 4000
KelvinCoolDaylight = 4500
KelvinSoftDaylight = 5000
KelvinDaylight = 5600
KelvinNoonDaylight = 6000
KelvinBrightDaylight = 6500
KelvinCloudDaylight = 7000
KelvinBlueDaylight = 7500
KelvinBlueOvercast = 8000
KelvinBlueIce = 9000
2020-03-22 19:40:41 +00:00
HueWhite = 0
HueRed = 0
HueOrange = 36
HueYellow = 60
HueGreen = 120
HueCyan = 180
HueBlue = 250
HuePurple = 280
HuePink = 325
2020-03-22 16:31:10 +00:00
)
var (
2020-03-22 16:31:10 +00:00
DefaultWhites = map[string]int{
2020-03-22 19:41:54 +00:00
"candlelight": KelvinCandlelight,
"sunset": KelvinSunset,
"ultrawarm": KelvinUltraWarm,
2020-03-28 18:29:35 +00:00
"incandescent": KelvinIncandescent,
2020-03-22 19:41:54 +00:00
"warm": KelvinWarm,
"cool": KelvinCool,
"cooldaylight": KelvinCoolDaylight,
"softdaylight": KelvinSoftDaylight,
"daylight": KelvinDaylight,
"noondaylight": KelvinNoonDaylight,
"brightdaylight": KelvinBrightDaylight,
"clouddaylight": KelvinCloudDaylight,
"bluedaylight": KelvinBlueDaylight,
"blueovercast": KelvinBlueOvercast,
"blueice": KelvinBlueIce,
2020-03-22 16:31:10 +00:00
}
)
2020-03-28 23:03:49 +00:00
func NewRGBColor(r, g, b uint8) (RGBColor, error) {
var c RGBColor
2020-03-24 05:26:06 +00:00
if (r < 0 || r > 255) && (g < 0 || r > 255) && (b < 0 || b > 255) {
2020-03-28 23:03:49 +00:00
return c, errors.New("values must be between 0-255")
2020-03-24 05:26:06 +00:00
}
2020-03-28 23:03:49 +00:00
return RGBColor{R: r, G: g, B: b}, nil
2020-02-29 22:00:21 +00:00
}
2020-03-22 19:40:41 +00:00
func NewHSColor(h, s float32) (HSBKColor, error) {
var c HSBKColor
if h < 0 || h > 360 {
return c, errors.New("hue must be between 0.0-360.0")
}
if s < 0 || s > 1 {
return c, errors.New("saturation must be between 0.0-1.0")
}
c = HSBKColor{
H: Float32Ptr(h),
S: Float32Ptr(s),
}
return c, nil
}
2020-03-08 18:47:01 +00:00
func NewHSBColor(h, s, b float32) (HSBKColor, error) {
2020-02-29 22:00:21 +00:00
var c HSBKColor
2020-03-08 18:47:01 +00:00
if h < 0 || h > 360 {
return c, errors.New("hue must be between 0.0-360.0")
}
if s < 0 || s > 1 {
return c, errors.New("saturation must be between 0.0-1.0")
}
if b < 0 || b > 1 {
return c, errors.New("brightness must be between 0.0-1.0")
}
c = HSBKColor{
H: Float32Ptr(h),
S: Float32Ptr(s),
B: Float32Ptr(b),
}
return c, nil
}
2020-03-22 19:40:41 +00:00
func NewRed() (HSBKColor, error) { return NewHSColor(HueRed, 1) }
func NewOrange() (HSBKColor, error) { return NewHSColor(HueOrange, 1) }
func NewYellow() (HSBKColor, error) { return NewHSColor(HueYellow, 1) }
func NewGreen() (HSBKColor, error) { return NewHSColor(HueGreen, 1) }
func NewCyan() (HSBKColor, error) { return NewHSColor(HueCyan, 1) }
func NewPurple() (HSBKColor, error) { return NewHSColor(HuePurple, 1) }
func NewPink() (HSBKColor, error) { return NewHSColor(HuePink, 1) }
2020-03-08 18:47:01 +00:00
func NewWhite(k int16) (HSBKColor, error) {
var c HSBKColor
2020-03-28 18:17:52 +00:00
if k < 1500 || k > 9000 {
2020-03-08 18:47:01 +00:00
return c, errors.New("kelvin must be between 1500-9000")
}
c = HSBKColor{
2020-03-22 19:41:54 +00:00
H: Float32Ptr(HueWhite),
2020-03-08 18:47:01 +00:00
S: Float32Ptr(0.0),
K: Int16Ptr(k),
}
return c, nil
2020-02-29 22:00:21 +00:00
}
2020-03-22 16:31:10 +00:00
func NewWhiteString(s string) (HSBKColor, error) {
k, ok := DefaultWhites[s]
if !ok {
return HSBKColor{}, fmt.Errorf("'%s' is not a valid default white", s)
}
return NewWhite(int16(k))
}
2020-02-29 22:00:21 +00:00
func (c RGBColor) ColorString() string {
return fmt.Sprintf("rgb:%d,%d,%d", c.R, c.G, c.B)
}
func (c RGBColor) Hex() string {
return fmt.Sprintf("#%x%x%x", c.R, c.G, c.B)
}
func (c HSBKColor) ColorString() string {
var s []string
2020-03-08 18:47:01 +00:00
if c.H != nil {
s = append(s, fmt.Sprintf("hue:%g", *c.H))
2020-02-29 22:00:21 +00:00
}
2020-03-08 18:47:01 +00:00
if c.S != nil {
s = append(s, fmt.Sprintf("saturation:%g", *c.S))
2020-02-29 22:00:21 +00:00
}
2020-03-08 18:47:01 +00:00
if c.B != nil {
s = append(s, fmt.Sprintf("brightness:%g", *c.B))
2020-02-29 22:00:21 +00:00
}
2020-03-08 18:47:01 +00:00
if c.K != nil {
s = append(s, fmt.Sprintf("kelvin:%d", *c.K))
2020-02-29 22:00:21 +00:00
}
return strings.Join(s, " ")
}
func (c HSBKColor) MarshalText() ([]byte, error) {
return []byte(c.ColorString()), nil
}
2020-02-29 22:09:05 +00:00
func (c NamedColor) ColorString() string {
return string(c)
}
2020-03-01 05:15:39 +00:00
func (c *Client) ValidateColor(color Color) (Color, error) {
2020-03-07 02:55:31 +00:00
var (
err error
s *HSBKColor
resp *http.Response
)
if resp, err = c.validateColor(color); err != nil {
2020-03-01 05:15:39 +00:00
return nil, err
}
2020-03-07 02:55:31 +00:00
fmt.Println(resp)
defer resp.Body.Close()
2020-03-01 05:15:39 +00:00
2020-03-07 02:55:31 +00:00
if err = json.NewDecoder(resp.Body).Decode(&s); err != nil {
2020-03-01 05:15:39 +00:00
return nil, err
}
return s, nil
}