This commit is contained in:
@@ -17,6 +17,7 @@ type Publisher struct {
|
||||
started map[int]bool
|
||||
pending map[int][]models.Device
|
||||
waiting map[int]chan struct{}
|
||||
sensorCache map[int]models.SceneSensor
|
||||
}
|
||||
|
||||
func (p *Publisher) SceneState(deviceID int) *models.DeviceState {
|
||||
@@ -42,6 +43,15 @@ func (p *Publisher) UpdateScene(data models.Scene) {
|
||||
p.mu.Unlock()
|
||||
}
|
||||
|
||||
func (p *Publisher) UpdateSensor(data models.SceneSensor) {
|
||||
p.mu.Lock()
|
||||
if assignment := p.sceneAssignment[data.ID]; assignment != nil {
|
||||
assignment.UpdateSensor(data)
|
||||
}
|
||||
p.sensorCache[data.ID] = data
|
||||
p.mu.Unlock()
|
||||
}
|
||||
|
||||
func (p *Publisher) ReloadScenes(ctx context.Context) error {
|
||||
scenes, err := config.SceneRepository().FetchAll(ctx)
|
||||
if err != nil {
|
||||
@@ -90,6 +100,10 @@ func (p *Publisher) Publish(devices ...models.Device) {
|
||||
|
||||
if p.sceneAssignment[device.ID] != nil {
|
||||
p.sceneAssignment[device.ID].UpsertDevice(device)
|
||||
|
||||
if cache, ok := p.sensorCache[device.ID]; ok {
|
||||
p.sceneAssignment[device.ID].UpdateSensor(cache)
|
||||
}
|
||||
} else {
|
||||
p.pending[device.BridgeID] = append(p.pending[device.BridgeID], device)
|
||||
if p.waiting[device.BridgeID] != nil {
|
||||
@@ -291,6 +305,7 @@ var publisher = Publisher{
|
||||
started: make(map[int]bool),
|
||||
pending: make(map[int][]models.Device),
|
||||
waiting: make(map[int]chan struct{}),
|
||||
sensorCache: make(map[int]models.SceneSensor),
|
||||
}
|
||||
|
||||
func Global() *Publisher {
|
||||
|
||||
@@ -13,11 +13,25 @@ type Scene struct {
|
||||
roleMap map[int]int
|
||||
roleList map[int][]models.Device
|
||||
lastStates map[int]models.DeviceState
|
||||
sensors []models.SceneSensor
|
||||
|
||||
due bool
|
||||
lastInterval int64
|
||||
}
|
||||
|
||||
func (s *Scene) UpdateSensor(data models.SceneSensor) {
|
||||
s.due = true
|
||||
|
||||
for i, sensor := range s.sensors {
|
||||
if sensor.ID == data.ID {
|
||||
s.sensors[i] = data
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
s.sensors = append(s.sensors, data)
|
||||
}
|
||||
|
||||
// UpdateScene updates the scene data and re-seats all devices.
|
||||
func (s *Scene) UpdateScene(data models.Scene) {
|
||||
devices := make([]models.Device, 0, 16)
|
||||
@@ -86,6 +100,13 @@ func (s *Scene) RemoveDevice(device models.Device) {
|
||||
|
||||
delete(s.roleMap, device.ID)
|
||||
delete(s.lastStates, device.ID)
|
||||
|
||||
for i, sensor := range s.sensors {
|
||||
if sensor.ID == device.ID {
|
||||
s.sensors = append(s.sensors[:i], s.sensors[i+1:]...)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Scene) Empty() bool {
|
||||
@@ -130,6 +151,7 @@ func (s *Scene) Run() []models.Device {
|
||||
return []models.Device{}
|
||||
}
|
||||
|
||||
currentTime := time.Now()
|
||||
intervalNumber := int64(0)
|
||||
intervalMax := int64(1)
|
||||
if s.data.IntervalMS > 0 {
|
||||
@@ -149,14 +171,31 @@ func (s *Scene) Run() []models.Device {
|
||||
continue
|
||||
}
|
||||
|
||||
sensorCount := 0
|
||||
for _, device := range list {
|
||||
if device.IsOnlySensor() {
|
||||
sensorCount += 1
|
||||
}
|
||||
}
|
||||
|
||||
role := s.data.Roles[i]
|
||||
|
||||
jSkip := 0
|
||||
|
||||
for j, device := range list {
|
||||
if device.IsOnlySensor() {
|
||||
updatedDevices = append(updatedDevices, device)
|
||||
jSkip += 1
|
||||
continue
|
||||
}
|
||||
|
||||
newState := role.ApplyEffect(&device, models.SceneRunContext{
|
||||
Index: j,
|
||||
Length: len(list),
|
||||
CurrentTime: currentTime,
|
||||
Index: j - jSkip,
|
||||
Length: len(list) - sensorCount,
|
||||
IntervalNumber: intervalNumber,
|
||||
IntervalMax: intervalMax,
|
||||
Sensors: s.sensors,
|
||||
})
|
||||
|
||||
err := device.SetState(newState)
|
||||
|
||||
Reference in New Issue
Block a user