|
|
@ -23,6 +23,7 @@ type Bridge struct { |
|
|
|
externalID int |
|
|
|
lightStates []*hueLightState |
|
|
|
sensorStates []*hueSensorState |
|
|
|
quarantine map[string]time.Time |
|
|
|
syncingPublish uint32 |
|
|
|
} |
|
|
|
|
|
|
@ -34,6 +35,10 @@ func (b *Bridge) Refresh(ctx context.Context) error { |
|
|
|
|
|
|
|
b.mu.Lock() |
|
|
|
for index, light := range lightMap { |
|
|
|
if time.Now().Before(b.quarantine[light.Uniqueid]) { |
|
|
|
continue |
|
|
|
} |
|
|
|
|
|
|
|
var state *hueLightState |
|
|
|
for _, existingState := range b.lightStates { |
|
|
|
if existingState.index == index { |
|
|
@ -68,6 +73,10 @@ func (b *Bridge) Refresh(ctx context.Context) error { |
|
|
|
|
|
|
|
b.mu.Lock() |
|
|
|
for index, sensor := range sensorMap { |
|
|
|
if time.Now().Before(b.quarantine[sensor.UniqueID]) { |
|
|
|
continue |
|
|
|
} |
|
|
|
|
|
|
|
var state *hueSensorState |
|
|
|
for _, existingState := range b.sensorStates { |
|
|
|
if existingState.index == index { |
|
|
@ -137,6 +146,44 @@ func (b *Bridge) SyncStale(ctx context.Context) error { |
|
|
|
return eg.Wait() |
|
|
|
} |
|
|
|
|
|
|
|
func (b *Bridge) ForgetDevice(ctx context.Context, device models.Device) error { |
|
|
|
// Find index
|
|
|
|
b.mu.Lock() |
|
|
|
found := false |
|
|
|
index := -1 |
|
|
|
for i, ls := range b.lightStates { |
|
|
|
if ls.uniqueID == device.InternalID { |
|
|
|
found = true |
|
|
|
index = i |
|
|
|
} |
|
|
|
} |
|
|
|
b.mu.Unlock() |
|
|
|
if !found { |
|
|
|
return models.ErrNotFound |
|
|
|
} |
|
|
|
|
|
|
|
// Delete light from bridge
|
|
|
|
err := b.deleteLight(ctx, index) |
|
|
|
if err != nil { |
|
|
|
return err |
|
|
|
} |
|
|
|
|
|
|
|
// Remove light state from local list. I don't know if the quarantine is necessary, but let's have it anyway.
|
|
|
|
b.mu.Lock() |
|
|
|
for i, ls := range b.lightStates { |
|
|
|
if ls.uniqueID == device.InternalID { |
|
|
|
b.lightStates = append(b.lightStates[:i], b.lightStates[i+1:]...) |
|
|
|
} |
|
|
|
} |
|
|
|
if b.quarantine == nil { |
|
|
|
b.quarantine = make(map[string]time.Time, 1) |
|
|
|
} |
|
|
|
b.quarantine[device.InternalID] = time.Now().Add(time.Second * 30) |
|
|
|
b.mu.Unlock() |
|
|
|
|
|
|
|
return nil |
|
|
|
} |
|
|
|
|
|
|
|
func (b *Bridge) SyncSensors(ctx context.Context) ([]models.Event, error) { |
|
|
|
sensorMap, err := b.getSensors(ctx) |
|
|
|
if err != nil { |
|
|
@ -175,6 +222,10 @@ func (b *Bridge) putGroupLightState(ctx context.Context, index int, input LightS |
|
|
|
return b.put(ctx, fmt.Sprintf("groups/%d/action", index), input, nil) |
|
|
|
} |
|
|
|
|
|
|
|
func (b *Bridge) deleteLight(ctx context.Context, index int) error { |
|
|
|
return b.delete(ctx, fmt.Sprintf("lights/%d", index), nil) |
|
|
|
} |
|
|
|
|
|
|
|
func (b *Bridge) getToken(ctx context.Context) (string, error) { |
|
|
|
result := make([]CreateUserResponse, 0, 1) |
|
|
|
err := b.post(ctx, "", CreateUserInput{DeviceType: "git.aiterp.net/lucifer"}, &result) |
|
|
|