Fix until_next and add test
This commit is contained in:
parent
b5906d06bd
commit
11b3622abe
13
main.go
13
main.go
@ -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")
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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,35 +364,55 @@ 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) {
|
||||
|
||||
timeNow = tt.getTime
|
||||
result := []Message{}
|
||||
|
||||
rchan := make(chan Message, 10)
|
||||
|
@ -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
|
||||
|
@ -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())
|
||||
|
Loading…
x
Reference in New Issue
Block a user