Browse Source

fixed hue updating too often, and change logic for fetchbyreference to support multiple tags, ids or bridges.

pull/1/head
Gisle Aune 3 years ago
parent
commit
2f9bd3c007
  1. 4
      app/services/events.go
  2. 13
      internal/drivers/hue/bridge.go
  3. 8
      internal/drivers/hue/driver.go
  4. 18
      internal/mysql/devicerepo.go

4
app/services/events.go

@ -49,7 +49,7 @@ func handleEvent(event models.Event) (responses []models.Event) {
startTime := time.Now()
defer func() {
duration := time.Since(startTime)
if duration > time.Millisecond * 250 {
if duration > time.Millisecond*250 {
log.Println(event.Name, "took long to handle:", duration)
}
}()
@ -134,7 +134,7 @@ func handleEvent(event models.Event) (responses []models.Event) {
if action.SetIntensity != nil {
newState.Intensity = action.SetIntensity
} else if action.AddIntensity != nil {
newIntensity := math.Max(0, math.Min(1, device.State.Intensity + *action.AddIntensity))
newIntensity := math.Max(0, math.Min(1, device.State.Intensity+*action.AddIntensity))
newState.Intensity = &newIntensity
}

13
internal/drivers/hue/bridge.go

@ -22,6 +22,7 @@ type Bridge struct {
externalID int
lightStates []*hueLightState
sensorStates []*hueSensorState
syncingPublish uint32
}
func (b *Bridge) Refresh(ctx context.Context) error {
@ -115,10 +116,20 @@ func (b *Bridge) SyncStale(ctx context.Context) error {
}
for i, input := range inputs {
iCopy := i
index := indices[i]
inputCopy := input
eg.Go(func() error { return b.putLightState(ctx, index, inputCopy) })
eg.Go(func() error {
err := b.putLightState(ctx, index, inputCopy)
if err != nil {
return err
}
b.lightStates[iCopy].stale = false
return nil
})
}
return eg.Wait()

8
internal/drivers/hue/driver.go

@ -10,6 +10,7 @@ import (
"net/http"
"strconv"
"sync"
"sync/atomic"
"time"
)
@ -309,6 +310,9 @@ func (d *Driver) Publish(ctx context.Context, bridge models.Bridge, devices []mo
}
b.mu.Unlock()
atomic.StoreUint32(&b.syncingPublish, 1)
defer atomic.StoreUint32(&b.syncingPublish, 0)
return b.SyncStale(ctx)
}
@ -327,6 +331,10 @@ func (d *Driver) Run(ctx context.Context, bridge models.Bridge, ch chan<- models
for {
select {
case <-selectedTicker.C:
if atomic.LoadUint32(&b.syncingPublish) == 1 {
continue
}
if ticksUntilRefresh <= 0 {
err := b.Refresh(ctx)
if err != nil {

18
internal/mysql/devicerepo.go

@ -56,22 +56,28 @@ func (r *DeviceRepo) Find(ctx context.Context, id int) (*models.Device, error) {
}
func (r *DeviceRepo) FetchByReference(ctx context.Context, kind models.ReferenceKind, value string) ([]models.Device, error) {
var err error
records := make([]deviceRecord, 0, 8)
q := sq.Select("device.*").From("device")
switch kind {
case models.RKDeviceID:
err = r.DBX.SelectContext(ctx, &records, "SELECT * FROM device WHERE id=?", value)
q = q.Where(sq.Eq{"id": strings.Split(value, ",")})
case models.RKBridgeID:
err = r.DBX.SelectContext(ctx, &records, "SELECT * FROM device WHERE bridge_id=?", value)
q = q.Where(sq.Eq{"bridge_id": strings.Split(value, ",")})
case models.RKTag:
err = r.DBX.SelectContext(ctx, &records, "SELECT device.* FROM device JOIN device_tag dt ON device.id = dt.device_id WHERE dt.tag_name=?", value)
q = q.Join("device_tag dt ON device.id=dt.device_id").Where(sq.Eq{"dt.tag_name": strings.Split(value, ",")})
case models.RKAll:
err = r.DBX.SelectContext(ctx, &records, "SELECT device.* FROM device")
default:
log.Println("Unknown reference kind used for device fetch:", kind)
return []models.Device{}, nil
}
query, args, err := q.ToSql()
if err != nil {
return nil, dbErr(err)
}
records := make([]deviceRecord, 0, 8)
err = r.DBX.SelectContext(ctx, &records, query, args...)
if err != nil {
return nil, dbErr(err)
}

Loading…
Cancel
Save