add sensor scenes for Motion and Temperature.
continuous-integration/drone/push Build is passing

This commit is contained in:
2021-10-30 14:38:14 +02:00
parent b191455753
commit 147231e4fd
7 changed files with 165 additions and 23 deletions
+15
View File
@@ -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 {
+41 -2
View File
@@ -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)