Fix until_next and add test

This commit is contained in:
Nicolas Duhamel 2022-10-28 16:14:47 +02:00
parent b5906d06bd
commit 11b3622abe
4 changed files with 75 additions and 34 deletions

13
main.go
View File

@ -150,6 +150,7 @@ func (app *App) onSettingsMessage(ctx context.Context, msg mqttpaho.Message) {
func (app *App) onSetStateMessage(ctx context.Context, msg mqttpaho.Message) {
// callback for topic /{prefix}/{tvr_id}/state/set change's
device_name := strings.Split(msg.Topic(), "/")[1]
logger := zerolog.Ctx(ctx).With().
@ -172,16 +173,10 @@ func (app *App) onSetStateMessage(ctx context.Context, msg mqttpaho.Message) {
return
}
if !device.SameState(state) {
device.State = state
if err := device.SetState(&logger, state, app.PubChan); err != nil {
logger.Error().Err(err).Msg("")
return
err := app.DeviceManager.Check(ctx, device_name)
if err != nil {
logger.Error().Err(err).Msg("error while checking device")
}
// device.SetState(log, state, pubchan)
} else {
logger.Info().Msg("no state update, ignoring")
}
}

View File

@ -317,6 +317,8 @@ func TestUpdate(t *testing.T) {
// device 3: currentSetpoint 0 always, 22
// device 4: currentSetpoint 22 until_time, fixed at timeNow, for 2h 22
// device 5: currentSetpoint 17 indem 4 but fixed timeNow-2h
// device 6: currentSetpoint 17, until_next set a timeNow, test time time now +1h : no change
timeNow = func() time.Time {
return test_time
@ -362,36 +364,56 @@ func TestUpdate(t *testing.T) {
Until_time: timeNow().Add(-1*time.Minute),
}
device6 := test_device
device6.Name = "6"
device6.CurrentSetpoint = 22
device6.State = DeviceState{
Mode: "until_next",
Setpoint: 22,
Time: timeNow(),
}
var tests = []struct{
getTime func() time.Time
device Device
want []Message
change bool
err error
}{
{device1, []Message{
{timeNow, device1, []Message{
Message{
Payload: []byte("{\"current_heating_setpoint\": 17}"),
Topic: "zigbee2mqtt/TVR/1/set",
Retain: false,
},
}, true, nil} ,
{device2, []Message{}, false, Error("device 2 don't have unknown program")},
{device3, []Message{
{timeNow, device2, []Message{}, false, Error("device 2 don't have unknown program")},
{timeNow, device3, []Message{
Message{
Payload: []byte("{\"current_heating_setpoint\": 22}"),
Topic: "zigbee2mqtt/TVR/3/set",
Retain: false,
},
}, true, nil} ,
{device4, []Message{}, false, nil} ,
{device5, []Message{}, true, nil} ,
{timeNow, device4, []Message{}, false, nil} ,
{timeNow, device5, []Message{}, true, nil} ,
{timeNow, device6, []Message{}, false, nil} ,
{func()time.Time{return test_time.Add(7*time.Hour+30*time.Minute)}, device6, []Message{
Message{
Payload: []byte("{\"current_heating_setpoint\": 19}"),
Topic: "zigbee2mqtt/TVR/6/set",
Retain: false,
},
}, true, nil} ,
}
for _, tt := range tests {
testname := fmt.Sprintf("%s", tt.device.Name )
t.Run(testname, func(t *testing.T) {
result := []Message{}
timeNow = tt.getTime
result := []Message{}
rchan := make(chan Message, 10)
errchan := make(chan error, 1)

View File

@ -104,42 +104,41 @@ func (p WeekProgram) Current() Setpoint {
func (p WeekProgram) NextTime(t time.Time) (time.Time, error) {
// return next program change
setpoint := Setpoint{}
var next time.Time
weekday := weekday(t)
daytime := daytime(t)
// Recursive func to find setpoint on weekday
get := func (weekday DayOfWeek, daytime int) Setpoint {
setpoint := Setpoint{}
get := func (weekday DayOfWeek, daytime int) (Setpoint, bool) {
for _, sp := range p[weekday] {
setpoint = sp
if daytime < sp.Start {
return setpoint
if daytime <= sp.Start {
return sp, true
}
}
return Setpoint{}
return Setpoint{}, false
}
startweekday := weekday
for (setpoint == Setpoint{}) {
setpoint = get(weekday, daytime)
if (setpoint != Setpoint{}) {
// setpoint found, compute time
next := time.Date(t.Year(), t.Month(), t.Day() + startweekday.DaysBetween(weekday), 0, 0, 0, 0, time.Local)
for {
if setpoint, ok := get(weekday, daytime); ok {
next := time.Date(t.Year(),
t.Month(),
t.Day() + startweekday.DaysBetween(weekday),
0, 0, 0, 0,
time.Local)
next = next.Add(time.Duration( (setpoint.Start) * int(time.Minute) ))
next = next.Add(
time.Duration( (setpoint.Start) * int(time.Minute) ))
return next, nil
}
weekday = weekday.Next()
daytime = 0
if weekday == startweekday {
return next, fmt.Errorf("Shouldn't happen no setpoint found over the week")
return time.Time{}, fmt.Errorf("Shouldn't happen no setpoint found over the week")
}
}
return next, nil
}
type Programs map[string]WeekProgram

View File

@ -39,7 +39,12 @@ func TestNextTime(t *testing.T) {
{Start: 22*60, Preset_id: 0},
}
program := WeekProgram{
zeroSetpoints := []Setpoint{
{Start: 0, Preset_id: 0},
}
default_program := WeekProgram{
Monday: defaultSetpoints,
Thuesday: defaultSetpoints,
Wednesday: defaultSetpoints,
@ -49,29 +54,49 @@ func TestNextTime(t *testing.T) {
Sunday: defaultSetpoints,
}
zero_program := WeekProgram{
Monday: zeroSetpoints,
Thuesday: zeroSetpoints,
Wednesday: zeroSetpoints,
Thursday : zeroSetpoints,
Friday: zeroSetpoints,
Saturday: zeroSetpoints,
Sunday: zeroSetpoints,
}
var tests = []struct{
prog WeekProgram
time time.Time
want time.Time
}{
{
default_program,
time.Date(2022, time.October, 23, 9, 0, 0, 0, time.Local),
time.Date(2022, time.October, 23, 16, 0, 0, 0, time.Local),
},
{
default_program,
time.Date(2022, time.October, 24, 5, 0, 0, 0, time.Local),
time.Date(2022, time.October, 24, 7, 0, 0, 0, time.Local),
},
{
default_program,
time.Date(2022, time.October, 23, 23, 0, 0, 0, time.Local),
time.Date(2022, time.October, 24, 7, 0, 0, 0, time.Local),
},
{
zero_program,
time.Date(2022, time.October, 23, 23, 0, 0, 0, time.Local),
time.Date(2022, time.October, 24, 0, 0, 0, 0, time.Local),
},
}
for _, tt := range tests {
testname := fmt.Sprintf("%s", tt.time.String() )
t.Run(testname, func(t *testing.T) {
next, err := program.NextTime(tt.time)
next, err := tt.prog.NextTime(tt.time)
if err != nil {
t.Fatalf("unexpected error")
t.Fatalf(err.Error())
}
if !next.Equal(tt.want) {
t.Errorf("got %s, want %s", next.String(), tt.want.String())