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) {
|
func (app *App) onSetStateMessage(ctx context.Context, msg mqttpaho.Message) {
|
||||||
// callback for topic /{prefix}/{tvr_id}/state/set change's
|
// callback for topic /{prefix}/{tvr_id}/state/set change's
|
||||||
|
|
||||||
device_name := strings.Split(msg.Topic(), "/")[1]
|
device_name := strings.Split(msg.Topic(), "/")[1]
|
||||||
|
|
||||||
logger := zerolog.Ctx(ctx).With().
|
logger := zerolog.Ctx(ctx).With().
|
||||||
@ -172,16 +173,10 @@ func (app *App) onSetStateMessage(ctx context.Context, msg mqttpaho.Message) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if !device.SameState(state) {
|
if err := device.SetState(&logger, state, app.PubChan); err != nil {
|
||||||
device.State = state
|
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 3: currentSetpoint 0 always, 22
|
||||||
// device 4: currentSetpoint 22 until_time, fixed at timeNow, for 2h 22
|
// device 4: currentSetpoint 22 until_time, fixed at timeNow, for 2h 22
|
||||||
// device 5: currentSetpoint 17 indem 4 but fixed timeNow-2h
|
// 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 {
|
timeNow = func() time.Time {
|
||||||
return test_time
|
return test_time
|
||||||
@ -362,36 +364,56 @@ func TestUpdate(t *testing.T) {
|
|||||||
Until_time: timeNow().Add(-1*time.Minute),
|
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{
|
var tests = []struct{
|
||||||
|
getTime func() time.Time
|
||||||
device Device
|
device Device
|
||||||
want []Message
|
want []Message
|
||||||
change bool
|
change bool
|
||||||
err error
|
err error
|
||||||
}{
|
}{
|
||||||
{device1, []Message{
|
{timeNow, device1, []Message{
|
||||||
Message{
|
Message{
|
||||||
Payload: []byte("{\"current_heating_setpoint\": 17}"),
|
Payload: []byte("{\"current_heating_setpoint\": 17}"),
|
||||||
Topic: "zigbee2mqtt/TVR/1/set",
|
Topic: "zigbee2mqtt/TVR/1/set",
|
||||||
Retain: false,
|
Retain: false,
|
||||||
},
|
},
|
||||||
}, true, nil} ,
|
}, true, nil} ,
|
||||||
{device2, []Message{}, false, Error("device 2 don't have unknown program")},
|
{timeNow, device2, []Message{}, false, Error("device 2 don't have unknown program")},
|
||||||
{device3, []Message{
|
{timeNow, device3, []Message{
|
||||||
Message{
|
Message{
|
||||||
Payload: []byte("{\"current_heating_setpoint\": 22}"),
|
Payload: []byte("{\"current_heating_setpoint\": 22}"),
|
||||||
Topic: "zigbee2mqtt/TVR/3/set",
|
Topic: "zigbee2mqtt/TVR/3/set",
|
||||||
Retain: false,
|
Retain: false,
|
||||||
},
|
},
|
||||||
}, true, nil} ,
|
}, true, nil} ,
|
||||||
{device4, []Message{}, false, nil} ,
|
{timeNow, device4, []Message{}, false, nil} ,
|
||||||
{device5, []Message{}, true, 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 {
|
for _, tt := range tests {
|
||||||
testname := fmt.Sprintf("%s", tt.device.Name )
|
testname := fmt.Sprintf("%s", tt.device.Name )
|
||||||
t.Run(testname, func(t *testing.T) {
|
t.Run(testname, func(t *testing.T) {
|
||||||
|
|
||||||
result := []Message{}
|
timeNow = tt.getTime
|
||||||
|
result := []Message{}
|
||||||
|
|
||||||
rchan := make(chan Message, 10)
|
rchan := make(chan Message, 10)
|
||||||
errchan := make(chan error, 1)
|
errchan := make(chan error, 1)
|
||||||
|
@ -104,42 +104,41 @@ func (p WeekProgram) Current() Setpoint {
|
|||||||
|
|
||||||
func (p WeekProgram) NextTime(t time.Time) (time.Time, error) {
|
func (p WeekProgram) NextTime(t time.Time) (time.Time, error) {
|
||||||
// return next program change
|
// return next program change
|
||||||
setpoint := Setpoint{}
|
|
||||||
var next time.Time
|
|
||||||
|
|
||||||
weekday := weekday(t)
|
weekday := weekday(t)
|
||||||
daytime := daytime(t)
|
daytime := daytime(t)
|
||||||
|
|
||||||
// Recursive func to find setpoint on weekday
|
// Recursive func to find setpoint on weekday
|
||||||
get := func (weekday DayOfWeek, daytime int) Setpoint {
|
get := func (weekday DayOfWeek, daytime int) (Setpoint, bool) {
|
||||||
setpoint := Setpoint{}
|
|
||||||
for _, sp := range p[weekday] {
|
for _, sp := range p[weekday] {
|
||||||
setpoint = sp
|
if daytime <= sp.Start {
|
||||||
if daytime < sp.Start {
|
return sp, true
|
||||||
return setpoint
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return Setpoint{}
|
return Setpoint{}, false
|
||||||
}
|
}
|
||||||
|
|
||||||
startweekday := weekday
|
startweekday := weekday
|
||||||
for (setpoint == Setpoint{}) {
|
for {
|
||||||
setpoint = get(weekday, daytime)
|
if setpoint, ok := get(weekday, daytime); ok {
|
||||||
if (setpoint != Setpoint{}) {
|
next := time.Date(t.Year(),
|
||||||
// setpoint found, compute time
|
t.Month(),
|
||||||
next := time.Date(t.Year(), t.Month(), t.Day() + startweekday.DaysBetween(weekday), 0, 0, 0, 0, time.Local)
|
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
|
return next, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
weekday = weekday.Next()
|
weekday = weekday.Next()
|
||||||
daytime = 0
|
daytime = 0
|
||||||
if weekday == startweekday {
|
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
|
type Programs map[string]WeekProgram
|
||||||
|
@ -39,7 +39,12 @@ func TestNextTime(t *testing.T) {
|
|||||||
{Start: 22*60, Preset_id: 0},
|
{Start: 22*60, Preset_id: 0},
|
||||||
}
|
}
|
||||||
|
|
||||||
program := WeekProgram{
|
zeroSetpoints := []Setpoint{
|
||||||
|
{Start: 0, Preset_id: 0},
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
default_program := WeekProgram{
|
||||||
Monday: defaultSetpoints,
|
Monday: defaultSetpoints,
|
||||||
Thuesday: defaultSetpoints,
|
Thuesday: defaultSetpoints,
|
||||||
Wednesday: defaultSetpoints,
|
Wednesday: defaultSetpoints,
|
||||||
@ -49,29 +54,49 @@ func TestNextTime(t *testing.T) {
|
|||||||
Sunday: defaultSetpoints,
|
Sunday: defaultSetpoints,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
zero_program := WeekProgram{
|
||||||
|
Monday: zeroSetpoints,
|
||||||
|
Thuesday: zeroSetpoints,
|
||||||
|
Wednesday: zeroSetpoints,
|
||||||
|
Thursday : zeroSetpoints,
|
||||||
|
Friday: zeroSetpoints,
|
||||||
|
Saturday: zeroSetpoints,
|
||||||
|
Sunday: zeroSetpoints,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
var tests = []struct{
|
var tests = []struct{
|
||||||
|
prog WeekProgram
|
||||||
time time.Time
|
time time.Time
|
||||||
want 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, 9, 0, 0, 0, time.Local),
|
||||||
time.Date(2022, time.October, 23, 16, 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, 5, 0, 0, 0, time.Local),
|
||||||
time.Date(2022, time.October, 24, 7, 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, 23, 23, 0, 0, 0, time.Local),
|
||||||
time.Date(2022, time.October, 24, 7, 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 {
|
for _, tt := range tests {
|
||||||
testname := fmt.Sprintf("%s", tt.time.String() )
|
testname := fmt.Sprintf("%s", tt.time.String() )
|
||||||
t.Run(testname, func(t *testing.T) {
|
t.Run(testname, func(t *testing.T) {
|
||||||
next, err := program.NextTime(tt.time)
|
next, err := tt.prog.NextTime(tt.time)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unexpected error")
|
t.Fatalf(err.Error())
|
||||||
}
|
}
|
||||||
if !next.Equal(tt.want) {
|
if !next.Equal(tt.want) {
|
||||||
t.Errorf("got %s, want %s", next.String(), tt.want.String())
|
t.Errorf("got %s, want %s", next.String(), tt.want.String())
|
||||||
|
Loading…
x
Reference in New Issue
Block a user