Browse Source

add device search.

feature-colorvalue2
Gisle Aune 2 years ago
parent
commit
27fd858c04
  1. 49
      internal/drivers/hue2/bridge.go
  2. 43
      internal/drivers/hue2/client.go
  3. 3
      internal/drivers/hue2/data.go
  4. 2
      internal/drivers/hue2/driver.go

49
internal/drivers/hue2/bridge.go

@ -556,3 +556,52 @@ func (b *Bridge) applyPatches(patches []ResourceData) {
b.resources = newResources
b.mu.Unlock()
}
func (b *Bridge) SearchDevices(ctx context.Context, timeout time.Duration) ([]models.Device, error) {
// Record the current state.
b.mu.Lock()
before := b.resources
b.mu.Unlock()
// Spend half the time waiting for devices
// TODO: Wait for v2 endpoint
err := b.client.LegacyDiscover(ctx, "sensors")
if err != nil {
return nil, err
}
select {
case <-time.After(timeout / 1):
case <-ctx.Done():
return nil, ctx.Err()
}
// Spend half the time waiting for lights
// TODO: Wait for v2 endpoint
err = b.client.LegacyDiscover(ctx, "lights")
if err != nil {
return nil, err
}
select {
case <-time.After(timeout / 1):
case <-ctx.Done():
return nil, ctx.Err()
}
// Perform a full refresh.
err = b.RefreshAll(ctx)
if err != nil {
return nil, err
}
// Check for new devices
devices := b.GenerateDevices()
newDevices := make([]models.Device, 0)
for _, device := range devices {
if before[device.InternalID] == nil {
newDevices = append(newDevices, device)
}
}
// Return said devices.
return newDevices, nil
}

43
internal/drivers/hue2/client.go

@ -92,8 +92,12 @@ func (c *Client) UpdateResource(ctx context.Context, link ResourceLink, update R
return c.put(ctx, link.Path(), update, nil)
}
func (c *Client) LegacyDiscover(ctx context.Context, kind string) error {
return c.legacyPost(ctx, kind, nil, nil)
}
func (c *Client) SSE(ctx context.Context) <-chan SSEUpdate {
ch := make(chan SSEUpdate, 4)0
ch := make(chan SSEUpdate, 4)
go func() {
defer close(ch)
@ -264,6 +268,43 @@ func (c *Client) post(ctx context.Context, path string, body interface{}, target
return json.NewDecoder(res.Body).Decode(&target)
}
func (c *Client) legacyPost(ctx context.Context, resource string, body interface{}, target interface{}) error {
select {
case <-ctx.Done():
return ctx.Err()
case <-c.ch:
defer func() {
c.ch <- struct{}{}
}()
}
rb, err := reqBody(body)
if err != nil {
return err
}
if c.token != "" {
resource = c.token + "/" + resource
}
req, err := http.NewRequest("POST", fmt.Sprintf("http://%s/api/%s", c.host, resource), rb)
if err != nil {
return err
}
res, err := httpClient.Do(req.WithContext(ctx))
if err != nil {
return err
}
defer res.Body.Close()
if target == nil {
return nil
}
return json.NewDecoder(res.Body).Decode(target)
}
func reqBody(body interface{}) (io.Reader, error) {
if body == nil {
return nil, nil

3
internal/drivers/hue2/data.go

@ -5,7 +5,6 @@ import (
"encoding/xml"
"fmt"
"git.aiterp.net/lucifer/new-server/models"
"log"
"strings"
"time"
)
@ -205,8 +204,6 @@ func (r ResourceUpdate) MarshalJSON() ([]byte, error) {
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
}

2
internal/drivers/hue2/driver.go

@ -83,7 +83,7 @@ func (d *Driver) SearchBridge(ctx context.Context, address, token string, dryRun
}
func (d *Driver) SearchDevices(ctx context.Context, bridge models.Bridge, timeout time.Duration) ([]models.Device, error) {
return nil, nil
return d.ensureBridge(bridge).SearchDevices(ctx, timeout)
}
func (d *Driver) ListDevices(_ context.Context, bridge models.Bridge) ([]models.Device, error) {

Loading…
Cancel
Save