Browse Source

change presence events, fix non-eq conditions.

feature-colorvalue2
Gisle Aune 3 years ago
parent
commit
ad2f912a6f
  1. 7
      internal/drivers/hue/bridge.go
  2. 38
      internal/drivers/hue/state.go
  3. 6
      models/eventhandler.go
  4. 2
      models/timeofday.go
  5. 40
      models/timeofday_test.go

7
internal/drivers/hue/bridge.go

@ -76,9 +76,10 @@ func (b *Bridge) Refresh(ctx context.Context) error {
if state == nil {
state = &hueSensorState{
index: index,
uniqueID: sensor.UniqueID,
externalID: -1,
index: index,
uniqueID: sensor.UniqueID,
externalID: -1,
presenceCooldown: -2,
}
b.sensorStates = append(b.sensorStates, state)

38
internal/drivers/hue/state.go

@ -92,7 +92,7 @@ type hueSensorState struct {
uniqueID string
prevData *SensorData
prevTime time.Time
presenceCooldown bool
presenceCooldown int
}
func (state *hueSensorState) Update(newData SensorData) *models.Event {
@ -153,26 +153,36 @@ func (state *hueSensorState) Update(newData SensorData) *models.Event {
case "ZLLPresence":
{
if state.prevData != nil && state.prevData.State.Presence != newData.State.Presence {
name := models.ENSensorPresenceStarted
if !newData.State.Presence {
name = models.ENSensorPresenceEnding
state.presenceCooldown = true
if newData.State.Presence {
state.presenceCooldown = -1
return &models.Event{
Name: models.ENSensorPresenceStarted,
Payload: map[string]string{
"deviceId": strconv.Itoa(state.externalID),
"deviceInternalId": newData.UniqueID,
},
}
} else {
state.presenceCooldown = 0
}
}
if state.presenceCooldown == -2 {
state.presenceCooldown = int(time.Since(stateTime) / time.Minute)
}
nextEventWait := time.Minute * time.Duration(state.presenceCooldown)
if state.presenceCooldown != -1 && !newData.State.Presence && time.Since(stateTime) > nextEventWait {
state.presenceCooldown += 1
return &models.Event{
Name: name,
Payload: map[string]string{
"deviceId": strconv.Itoa(state.externalID),
"deviceInternalId": newData.UniqueID,
},
}
} else if state.presenceCooldown && !newData.State.Presence && time.Since(stateTime) > time.Minute {
state.presenceCooldown = false
return &models.Event{
Name: models.ENSensorPresenceEnded,
Payload: map[string]string{
"deviceId": strconv.Itoa(state.externalID),
"deviceInternalId": newData.UniqueID,
"minutesElapsed": strconv.Itoa(state.presenceCooldown - 1),
"secondsElapsed": strconv.Itoa((state.presenceCooldown - 1) * 60),
},
}
}

6
models/eventhandler.go

@ -173,11 +173,11 @@ func (c *EventCondition) checkDevice(key string, device Device) (matches bool, s
}
}
var numRegex = regexp.MustCompile("^{-[0-9].}+$")
var numRegex = regexp.MustCompile("^-*[0-9]+(.[0-9]+)*$")
func (c *EventCondition) matches(value string) bool {
if numRegex.MatchString(value) {
numValue, _ := strconv.ParseFloat(c.LT, 64)
numValue, _ := strconv.ParseFloat(value, 64)
stillAlive := true
if c.LT != "" {
@ -197,7 +197,7 @@ func (c *EventCondition) matches(value string) bool {
if stillAlive && c.GTE != "" {
gte, _ := strconv.ParseFloat(c.GTE, 64)
stillAlive = numValue == gte
stillAlive = numValue >= gte
}
if stillAlive && c.GT != "" {

2
models/timeofday.go

@ -75,7 +75,7 @@ func (t TimeOfDay) IsBetween(from TimeOfDay, to TimeOfDay) bool {
if from == to {
return t == from
} else if from > to {
return t >= to || t <= from
return t >= from || t <= to
} else {
return t >= from && t <= to
}

40
models/timeofday_test.go

@ -0,0 +1,40 @@
package models
import (
"fmt"
"testing"
)
func tod(s string) TimeOfDay {
tod, err := ParseTimeOfDay(s)
if err != nil {
panic(err)
}
return tod
}
func TestTimeOfDay_IsBetween(t *testing.T) {
table := []struct{
Value TimeOfDay
From TimeOfDay
To TimeOfDay
Expected bool
}{
{ tod("16:13:11"), tod("07"), tod("21:30"), true },
{ tod("16:13:31"), tod("21:30"), tod("07"), false },
{ tod("23:15:32"), tod("21:30"), tod("07"), true },
{ tod("04:13:57"), tod("21:30"), tod("07"), true },
{ tod("16:14:43"), tod("15:30"), tod("16:00"), false },
{ tod("16:14:43"), tod("15:30"), tod("16:15"), true },
}
for i, row := range table {
t.Run(fmt.Sprintf("row_%d", i), func (t *testing.T) {
if row.Value.IsBetween(row.From, row.To) != row.Expected {
t.Log(row.Value, row.From, row.To)
t.Fail()
}
})
}
}
Loading…
Cancel
Save