diff --git a/app/services/publisher/publisher.go b/app/services/publisher/publisher.go index 2550e84..4f3b853 100644 --- a/app/services/publisher/publisher.go +++ b/app/services/publisher/publisher.go @@ -110,16 +110,19 @@ func (p *Publisher) Run() { ticker := time.NewTicker(time.Millisecond * 100) deleteList := make([]int, 0, 8) updatedList := make([]models.Device, 0, 16) + reassignList := make([]models.Device, 0, 16) for range ticker.C { deleteList = deleteList[:0] updatedList = updatedList[:0] + reassignList = reassignList[:0] p.mu.Lock() for i, scene := range p.scenes { if (!scene.endTime.IsZero() && time.Now().After(scene.endTime)) || scene.Empty() { deleteList = append(deleteList, i-len(deleteList)) updatedList = append(updatedList, scene.AllDevices()...) + reassignList = append(reassignList, scene.AllDevices()...) log.Printf("Removing scene instance for %s (%d)", scene.data.Name, scene.data.ID) @@ -139,6 +142,14 @@ func (p *Publisher) Run() { p.scenes = append(p.scenes[:i], p.scenes[i+1:]...) } + for _, device := range reassignList { + p.reassignDevice(device) + + if p.sceneAssignment[device.ID] != nil { + p.sceneAssignment[device.ID].UpsertDevice(device) + } + } + for _, device := range updatedList { if !p.started[device.BridgeID] { p.started[device.BridgeID] = true @@ -159,10 +170,10 @@ func (p *Publisher) Run() { // should trigger an update. func (p *Publisher) reassignDevice(device models.Device) bool { var selectedAssignment *models.DeviceSceneAssignment - for _, assignment := range device.SceneAssignments { + for i, assignment := range device.SceneAssignments { duration := time.Duration(assignment.DurationMS) * time.Millisecond if duration <= 0 || time.Now().Before(assignment.StartTime.Add(duration)) { - selectedAssignment = &assignment + selectedAssignment = &device.SceneAssignments[i] } } diff --git a/models/eventhandler.go b/models/eventhandler.go index 0a7ea4f..4e6e410 100644 --- a/models/eventhandler.go +++ b/models/eventhandler.go @@ -171,7 +171,7 @@ func (c *EventCondition) checkDevice(key string, device Device) (matches bool, s return c.matches(strconv.FormatFloat(device.State.Temperature, 'f', -1, 64)), false case "scene": if len(device.SceneAssignments) == 0 { - return false, false + return c.matches("-1"), false } sceneId := -1