This commit is contained in:
@@ -222,17 +222,31 @@ func (b *Bridge) Update(devices ...models.Device) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (b *Bridge) MakeCongruent(ctx context.Context) (int, error) {
|
func (b *Bridge) MakeCongruent(ctx context.Context) (int, error) {
|
||||||
// Eat the event if there's a pending update.
|
// Eat all event if there's a pending update.
|
||||||
select {
|
exhausted := false
|
||||||
case <-b.needsUpdate:
|
for !exhausted {
|
||||||
default:
|
select {
|
||||||
|
case <-b.needsUpdate:
|
||||||
|
default:
|
||||||
|
exhausted = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
b.mu.Lock()
|
b.mu.Lock()
|
||||||
dur := time.Millisecond * 200
|
dur := time.Millisecond * 100
|
||||||
updates := make(map[string]ResourceUpdate)
|
updates := make(map[string]ResourceUpdate)
|
||||||
for _, device := range b.devices {
|
for _, device := range b.devices {
|
||||||
resource := b.resources[device.InternalID]
|
resource := b.resources[device.InternalID]
|
||||||
|
|
||||||
|
// Update device
|
||||||
|
if resource.Metadata.Name != device.Name {
|
||||||
|
name := device.Name
|
||||||
|
updates["device/"+resource.ID] = ResourceUpdate{
|
||||||
|
Name: &name,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update light
|
||||||
if lightID := resource.ServiceID("light"); lightID != nil {
|
if lightID := resource.ServiceID("light"); lightID != nil {
|
||||||
light := b.resources[*lightID]
|
light := b.resources[*lightID]
|
||||||
update := ResourceUpdate{TransitionDuration: &dur}
|
update := ResourceUpdate{TransitionDuration: &dur}
|
||||||
@@ -286,13 +300,14 @@ func (b *Bridge) MakeCongruent(ctx context.Context) (int, error) {
|
|||||||
return 0, nil
|
return 0, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Println(fmt.Sprintf("[Bridge %d]", b.externalID), "Updating", len(updates), "services...")
|
log.Println(fmt.Sprintf("[Bridge %d]", b.externalID), "Updating", len(updates), "hue services...")
|
||||||
|
|
||||||
eg, ctx := errgroup.WithContext(ctx)
|
eg, ctx := errgroup.WithContext(ctx)
|
||||||
for key := range updates {
|
for key := range updates {
|
||||||
update := updates[key]
|
update := updates[key]
|
||||||
split := strings.SplitN(key, "/", 2)
|
split := strings.SplitN(key, "/", 2)
|
||||||
link := ResourceLink{Kind: split[0], ID: split[1]}
|
link := ResourceLink{Kind: split[0], ID: split[1]}
|
||||||
|
|
||||||
eg.Go(func() error {
|
eg.Go(func() error {
|
||||||
return b.client.UpdateResource(ctx, link, update)
|
return b.client.UpdateResource(ctx, link, update)
|
||||||
})
|
})
|
||||||
@@ -334,6 +349,7 @@ func (b *Bridge) GenerateDevices() []models.Device {
|
|||||||
}
|
}
|
||||||
|
|
||||||
device := models.Device{
|
device := models.Device{
|
||||||
|
BridgeID: b.externalID,
|
||||||
InternalID: resource.ID,
|
InternalID: resource.ID,
|
||||||
Name: resource.Metadata.Name,
|
Name: resource.Metadata.Name,
|
||||||
DriverProperties: map[string]interface{}{
|
DriverProperties: map[string]interface{}{
|
||||||
@@ -530,6 +546,7 @@ func (b *Bridge) applyPatches(patches []ResourceData) {
|
|||||||
if patch.Status != nil {
|
if patch.Status != nil {
|
||||||
resCopy.Status = patch.Status
|
resCopy.Status = patch.Status
|
||||||
}
|
}
|
||||||
|
resCopy.Metadata.Name = patch.Metadata.Name
|
||||||
|
|
||||||
newResources[patch.ID] = &resCopy
|
newResources[patch.ID] = &resCopy
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ import (
|
|||||||
|
|
||||||
func NewClient(host, token string) *Client {
|
func NewClient(host, token string) *Client {
|
||||||
ch := make(chan struct{}, 5)
|
ch := make(chan struct{}, 5)
|
||||||
for i := 0; i < 3; i++ {
|
for i := 0; i < 2; i++ {
|
||||||
ch <- struct{}{}
|
ch <- struct{}{}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -93,7 +93,7 @@ func (c *Client) UpdateResource(ctx context.Context, link ResourceLink, update R
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) SSE(ctx context.Context) <-chan SSEUpdate {
|
func (c *Client) SSE(ctx context.Context) <-chan SSEUpdate {
|
||||||
ch := make(chan SSEUpdate, 4)
|
ch := make(chan SSEUpdate, 4)0
|
||||||
go func() {
|
go func() {
|
||||||
defer close(ch)
|
defer close(ch)
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
package hue2
|
package hue2
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
"encoding/xml"
|
"encoding/xml"
|
||||||
"fmt"
|
"fmt"
|
||||||
"git.aiterp.net/lucifer/new-server/models"
|
"git.aiterp.net/lucifer/new-server/models"
|
||||||
|
"log"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
@@ -89,6 +91,9 @@ func (res *ResourceData) ServiceIndex(kind string, id string) int {
|
|||||||
func (res *ResourceData) WithUpdate(update ResourceUpdate) *ResourceData {
|
func (res *ResourceData) WithUpdate(update ResourceUpdate) *ResourceData {
|
||||||
resCopy := *res
|
resCopy := *res
|
||||||
|
|
||||||
|
if update.Name != nil {
|
||||||
|
resCopy.Metadata.Name = *update.Name
|
||||||
|
}
|
||||||
if update.Power != nil {
|
if update.Power != nil {
|
||||||
cp := *resCopy.Power
|
cp := *resCopy.Power
|
||||||
resCopy.Power = &cp
|
resCopy.Power = &cp
|
||||||
@@ -170,6 +175,7 @@ type LightAlert struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type ResourceUpdate struct {
|
type ResourceUpdate struct {
|
||||||
|
Name *string
|
||||||
Power *bool
|
Power *bool
|
||||||
ColorXY *models.ColorXY
|
ColorXY *models.ColorXY
|
||||||
Brightness *float64
|
Brightness *float64
|
||||||
@@ -179,6 +185,10 @@ type ResourceUpdate struct {
|
|||||||
|
|
||||||
func (r ResourceUpdate) MarshalJSON() ([]byte, error) {
|
func (r ResourceUpdate) MarshalJSON() ([]byte, error) {
|
||||||
chunks := make([]string, 0, 4)
|
chunks := make([]string, 0, 4)
|
||||||
|
if r.Name != nil {
|
||||||
|
s, _ := json.Marshal(*r.Name)
|
||||||
|
chunks = append(chunks, fmt.Sprintf(`"metadata":{"name":%s}`, string(s)))
|
||||||
|
}
|
||||||
if r.Power != nil {
|
if r.Power != nil {
|
||||||
chunks = append(chunks, fmt.Sprintf(`"on":{"on":%v}`, *r.Power))
|
chunks = append(chunks, fmt.Sprintf(`"on":{"on":%v}`, *r.Power))
|
||||||
}
|
}
|
||||||
@@ -195,6 +205,8 @@ func (r ResourceUpdate) MarshalJSON() ([]byte, error) {
|
|||||||
chunks = append(chunks, fmt.Sprintf(`"dynamics":{"duration":%d}`, r.TransitionDuration.Truncate(time.Millisecond*100).Milliseconds()))
|
chunks = append(chunks, fmt.Sprintf(`"dynamics":{"duration":%d}`, r.TransitionDuration.Truncate(time.Millisecond*100).Milliseconds()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log.Println(fmt.Sprintf("{%s}", strings.Join(chunks, ",")))
|
||||||
|
|
||||||
return []byte(fmt.Sprintf("{%s}", strings.Join(chunks, ","))), nil
|
return []byte(fmt.Sprintf("{%s}", strings.Join(chunks, ","))), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user