diff --git a/internal/color/color.go b/internal/color/color.go index 2544119..ad9360a 100644 --- a/internal/color/color.go +++ b/internal/color/color.go @@ -126,6 +126,14 @@ func (col *Color) ToRGB() (col2 Color, ok bool) { ok = true } + if ok { + col2 = Color{RGB: &RGB{ + Red: math.Max(col2.RGB.Red, 0.0), + Green: math.Max(col2.RGB.Green, 0.0), + Blue: math.Max(col2.RGB.Blue, 0.0), + }} + } + return } @@ -309,7 +317,9 @@ func Parse(raw string) (col Color, err error) { return } - tokens := strings.SplitN(raw, ":", 2) + convertTokens := strings.SplitN(raw, "|", 2) + + tokens := strings.SplitN(convertTokens[0], ":", 2) if len(tokens) != 2 { err = ErrBadColorInput return @@ -434,6 +444,34 @@ func Parse(raw string) (col Color, err error) { err = ErrUnknownColorFormat } + if err == nil && len(convertTokens) == 2 { + switch convertTokens[1] { + case "xy": + col2, ok := col.ToXY() + if !ok { + err = ErrUnknownColorFormat + } else { + col = col2 + } + case "rgb": + col2, ok := col.ToRGB() + if !ok { + err = ErrUnknownColorFormat + } else { + col = col2 + } + case "hs": + col2, ok := col.ToHS() + if !ok { + err = ErrUnknownColorFormat + } else { + col = col2 + } + default: + err = ErrUnknownColorFormat + } + } + return } diff --git a/internal/color/rgb.go b/internal/color/rgb.go index 5c04ef5..711c20f 100644 --- a/internal/color/rgb.go +++ b/internal/color/rgb.go @@ -1,6 +1,9 @@ package color -import "github.com/lucasb-eyer/go-colorful" +import ( + "github.com/lucasb-eyer/go-colorful" + "math" +) type RGB struct { Red float64 `json:"red"` @@ -36,6 +39,14 @@ func (rgb RGB) ToXY() XY { } } +func (rgb RGB) Round() RGB { + return RGB{ + Red: math.Max(math.Round(rgb.Red*1000)/1000, 0), + Green: math.Max(math.Round(rgb.Green*1000)/1000, 0), + Blue: math.Max(math.Round(rgb.Blue*1000)/1000, 0), + } +} + func (rgb RGB) Normalize() (RGB, float64) { hue, sat, value := colorful.Color{R: rgb.Red, G: rgb.Green, B: rgb.Blue}.Hsv() hs := HueSat{Hue: hue, Sat: sat} diff --git a/internal/color/xy.go b/internal/color/xy.go index 03a9e34..fbdf7ba 100644 --- a/internal/color/xy.go +++ b/internal/color/xy.go @@ -162,13 +162,13 @@ type XY struct { func (xy XY) ToRGB() RGB { h, s, _ := colorful.Xyy(xy.X, xy.Y, 0.5).Hsv() - c := colorful.Hsv(h, s, 1) + c := colorful.Hsv(math.Mod(h, 360), s, 1) return RGB{Red: c.R, Green: c.G, Blue: c.B} } func (xy XY) ToHS() HueSat { h, s, _ := colorful.Xyy(xy.X, xy.Y, 0.5).Hsv() - return HueSat{Hue: h, Sat: s} + return HueSat{Hue: math.Mod(h, 360), Sat: s} } func (xy XY) DistanceTo(other XY) float64 { diff --git a/services/uistate/data.go b/services/uistate/data.go index 32c6d56..3604aec 100644 --- a/services/uistate/data.go +++ b/services/uistate/data.go @@ -4,6 +4,7 @@ import ( "git.aiterp.net/lucifer3/server/device" "git.aiterp.net/lucifer3/server/effects" "git.aiterp.net/lucifer3/server/events" + "git.aiterp.net/lucifer3/server/internal/color" "git.aiterp.net/lucifer3/server/internal/gentools" "github.com/google/uuid" ) @@ -25,6 +26,7 @@ func (d *Data) WithPatch(patches ...Patch) Data { gentools.ApplyUpdatePtr(&pd.HWMetadata, patch.Device.HWMetadata) gentools.ApplyUpdatePtr(&pd.DesiredState, patch.Device.DesiredState) gentools.ApplyUpdatePtr(&pd.Assignment, patch.Device.Assignment) + gentools.ApplyUpdatePtr(&pd.ActiveColorRGB, patch.Device.ActiveColorRGB) if patch.Device.AddAlias != nil { pd.Aliases = append(pd.Aliases[:0:0], pd.Aliases...) @@ -42,6 +44,9 @@ func (d *Data) WithPatch(patches ...Patch) Data { if patch.Device.ClearAssignment { pd.Assignment = nil } + if patch.Device.ClearActiveColorRGB { + pd.ActiveColorRGB = nil + } if patch.Device.Delete { delete(newData.Devices, pd.ID) @@ -102,13 +107,14 @@ func (d *Data) ensureAssignment(id uuid.UUID) Assignment { } type Device struct { - ID string `json:"id"` - Name string `json:"name"` - HWMetadata *events.HardwareMetadata `json:"hwMetadata"` - HWState *events.HardwareState `json:"hwState"` - DesiredState *device.State `json:"desiredState"` - Aliases []string `json:"aliases"` - Assignment *uuid.UUID `json:"assignment"` + ID string `json:"id"` + Name string `json:"name"` + HWMetadata *events.HardwareMetadata `json:"hwMetadata"` + HWState *events.HardwareState `json:"hwState"` + ActiveColorRGB *color.RGB `json:"activeColorRgb"` + DesiredState *device.State `json:"desiredState"` + Aliases []string `json:"aliases"` + Assignment *uuid.UUID `json:"assignment"` } type Assignment struct { diff --git a/services/uistate/patch.go b/services/uistate/patch.go index 06b1a24..33724b6 100644 --- a/services/uistate/patch.go +++ b/services/uistate/patch.go @@ -5,6 +5,7 @@ import ( "git.aiterp.net/lucifer3/server/device" "git.aiterp.net/lucifer3/server/effects" "git.aiterp.net/lucifer3/server/events" + "git.aiterp.net/lucifer3/server/internal/color" "github.com/google/uuid" ) @@ -29,17 +30,19 @@ func (e Patch) EventDescription() string { } type DevicePatch struct { - ID string `json:"id,omitempty"` - Name *string `json:"name,omitempty"` - HWMetadata *events.HardwareMetadata `json:"hwMetadata,omitempty"` - HWState *events.HardwareState `json:"hwState,omitempty"` - DesiredState *device.State `json:"desiredState,omitempty"` - SetAliases []string `json:"setAliases,omitempty"` - AddAlias *string `json:"addAlias,omitempty"` - RemoveAlias *string `json:"removeAlias,omitempty"` - Assignment *uuid.UUID `json:"assignment,omitempty"` - ClearAssignment bool `json:"clearAssignment,omitempty"` - Delete bool `json:"delete,omitempty"` + ID string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + HWMetadata *events.HardwareMetadata `json:"hwMetadata,omitempty"` + HWState *events.HardwareState `json:"hwState,omitempty"` + DesiredState *device.State `json:"desiredState,omitempty"` + SetAliases []string `json:"setAliases,omitempty"` + AddAlias *string `json:"addAlias,omitempty"` + RemoveAlias *string `json:"removeAlias,omitempty"` + Assignment *uuid.UUID `json:"assignment,omitempty"` + ClearAssignment bool `json:"clearAssignment,omitempty"` + ActiveColorRGB *color.RGB `json:"activeColorRgb"` + ClearActiveColorRGB bool `json:"clearActiveColorRGB"` + Delete bool `json:"delete,omitempty"` } type AssignmentPatch struct { diff --git a/services/uistate/service.go b/services/uistate/service.go index 0126c1a..2fb75ac 100644 --- a/services/uistate/service.go +++ b/services/uistate/service.go @@ -56,6 +56,18 @@ func (s *service) HandleEvent(bus *lucifer3.EventBus, event lucifer3.Event) { patches = []Patch{{Device: &DevicePatch{ID: event.ID, RemoveAlias: &event.Alias}}} case events.HardwareState: patches = []Patch{{Device: &DevicePatch{ID: event.ID, HWState: &event}}} + if event.State.Color != nil { + rgb, _ := event.State.Color.ToRGB() + patches = append(patches, Patch{Device: &DevicePatch{ + ID: event.ID, + ActiveColorRGB: gentools.Ptr(rgb.RGB.Round()), + }}) + } else { + patches = append(patches, Patch{Device: &DevicePatch{ + ID: event.ID, + ClearActiveColorRGB: false, + }}) + } case events.HardwareMetadata: patches = []Patch{{Device: &DevicePatch{ID: event.ID, HWMetadata: &event}}} case events.AssignmentCreated: