gofmt
This commit is contained in:
parent
11b3622abe
commit
6837a07beb
56
main.go
56
main.go
@ -1,18 +1,19 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"citadel/heater/pkg/device"
|
||||
"citadel/heater/mqtt"
|
||||
mqttpaho "github.com/eclipse/paho.mqtt.golang"
|
||||
"citadel/heater/pkg/device"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"flag"
|
||||
"os"
|
||||
"os/signal"
|
||||
"strings"
|
||||
"syscall"
|
||||
"time"
|
||||
"strings"
|
||||
|
||||
mqttpaho "github.com/eclipse/paho.mqtt.golang"
|
||||
"github.com/rs/zerolog"
|
||||
"flag"
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
@ -58,7 +59,7 @@ func (app *App) subscribe(
|
||||
topic string,
|
||||
qos int,
|
||||
callback func(context.Context, mqttpaho.Message),
|
||||
) context.CancelFunc {
|
||||
) context.CancelFunc {
|
||||
|
||||
ctx, cancelFunc := context.WithCancel(app.ctx)
|
||||
|
||||
@ -95,7 +96,7 @@ func (app *App) runTicker() {
|
||||
go func() {
|
||||
for {
|
||||
select {
|
||||
case <- app.ctx.Done():
|
||||
case <-app.ctx.Done():
|
||||
return
|
||||
case t := <-ticker.C:
|
||||
logger.Info().Time("at", t).Msg("Tick")
|
||||
@ -115,9 +116,13 @@ func (app *App) onSettingsMessage(ctx context.Context, msg mqttpaho.Message) {
|
||||
Str("device", device_name).
|
||||
Logger()
|
||||
|
||||
logger.Debug().Str("topic", msg.Topic()).Str("payload", string(msg.Payload())).Msg("")
|
||||
ctx = logger.WithContext(ctx)
|
||||
|
||||
logger.Debug().
|
||||
Str("topic", msg.Topic()).
|
||||
Str("payload", string(msg.Payload())).
|
||||
Msg("")
|
||||
|
||||
var device_settings device.DeviceSettings
|
||||
if err := json.Unmarshal(msg.Payload(), &device_settings); err != nil {
|
||||
logger.Error().Err(err).Msg("Parsing payload")
|
||||
@ -129,21 +134,19 @@ func (app *App) onSettingsMessage(ctx context.Context, msg mqttpaho.Message) {
|
||||
}
|
||||
|
||||
if _, ok := app.DeviceManager.Get(device_name); !ok {
|
||||
err := app.DeviceManager.Add(tvr)
|
||||
if err != nil {
|
||||
logger.Error().Err(err).Msg("Unexpected")
|
||||
if err := app.DeviceManager.Add(tvr); err != nil {
|
||||
logger.Error().Err(err).Msg("unexpected, abord")
|
||||
return
|
||||
}
|
||||
} else {
|
||||
err := app.DeviceManager.SetSettings(device_name, device_settings)
|
||||
if err != nil {
|
||||
logger.Error().Err(err).Msg("Unexpected")
|
||||
if err := app.DeviceManager.
|
||||
SetSettings(device_name, device_settings); err != nil {
|
||||
logger.Error().Err(err).Msg("unexpected, abord")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
err := app.DeviceManager.Check(ctx, device_name)
|
||||
if err != nil {
|
||||
if err := app.DeviceManager.Check(ctx, device_name); err != nil {
|
||||
logger.Error().Err(err).Msg("During device `Check`")
|
||||
}
|
||||
}
|
||||
@ -159,29 +162,24 @@ func (app *App) onSetStateMessage(ctx context.Context, msg mqttpaho.Message) {
|
||||
Logger()
|
||||
ctx = logger.WithContext(ctx)
|
||||
|
||||
|
||||
var state device.DeviceState
|
||||
if err := json.Unmarshal(msg.Payload(), &state); err != nil {
|
||||
logger.Error().Err(err).Msg("Error while parsing payload")
|
||||
}
|
||||
|
||||
logger.Info().Interface("state", state).Msg("new state")
|
||||
|
||||
device, ok := app.DeviceManager.Get(device_name)
|
||||
if !ok {
|
||||
logger.Error().Msg("Device not found, abord")
|
||||
return
|
||||
}
|
||||
|
||||
logger.Debug().Interface("state", state).Msg("new state")
|
||||
|
||||
if device, ok := app.DeviceManager.Get(device_name); ok {
|
||||
if err := device.SetState(&logger, state, app.PubChan); err != nil {
|
||||
logger.Error().Err(err).Msg("")
|
||||
logger.Error().Err(err).Msg("unexpected")
|
||||
return
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
logger.Error().Msg("Device not found, abord")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func (app *App) Run() {
|
||||
ctx, ctxCancel := context.WithCancel(context.Background())
|
||||
output := zerolog.ConsoleWriter{Out: os.Stderr}
|
||||
@ -191,7 +189,6 @@ func (app *App) Run() {
|
||||
|
||||
ctx = log.WithContext(ctx)
|
||||
|
||||
|
||||
defer ctxCancel()
|
||||
|
||||
if err := app.mqtt_hub.Connect(ctx); err != nil {
|
||||
@ -221,7 +218,7 @@ func (app *App) Run() {
|
||||
Str("payload", string(msg.Payload)).
|
||||
Msg("publish")
|
||||
|
||||
pub.Publish(msg.Topic, 1 ,msg.Payload, msg.Retain)
|
||||
pub.Publish(msg.Topic, 1, msg.Payload, msg.Retain)
|
||||
|
||||
case err, ok := <-pub.OnError:
|
||||
if !ok {
|
||||
@ -271,4 +268,3 @@ func main() {
|
||||
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
|
||||
<-quit
|
||||
}
|
||||
|
||||
|
@ -1,13 +1,14 @@
|
||||
package device
|
||||
|
||||
import (
|
||||
"github.com/eclipse/paho.mqtt.golang"
|
||||
"github.com/ohler55/ojg/jp"
|
||||
"github.com/ohler55/ojg/oj"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"time"
|
||||
"encoding/json"
|
||||
"context"
|
||||
|
||||
mqtt "github.com/eclipse/paho.mqtt.golang"
|
||||
"github.com/ohler55/ojg/jp"
|
||||
"github.com/ohler55/ojg/oj"
|
||||
"github.com/rs/zerolog"
|
||||
// "reflect"
|
||||
)
|
||||
@ -16,10 +17,9 @@ var timeNow = func() time.Time {
|
||||
return time.Now()
|
||||
}
|
||||
|
||||
|
||||
type Error string
|
||||
func (e Error) Error() string { return string(e) }
|
||||
|
||||
func (e Error) Error() string { return string(e) }
|
||||
|
||||
type DeviceState struct {
|
||||
Mode string `json:"mode"`
|
||||
@ -62,7 +62,6 @@ func (s *DeviceState) Equivalent(state DeviceState) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
|
||||
// Internal state
|
||||
type Device struct {
|
||||
Name string
|
||||
@ -71,7 +70,6 @@ type Device struct {
|
||||
State DeviceState
|
||||
}
|
||||
|
||||
|
||||
func (d *Device) StateTopic() string {
|
||||
return fmt.Sprintf("heater/%s/state", d.Name)
|
||||
}
|
||||
@ -80,7 +78,6 @@ func (d Device) ListenTopic() (string, error) {
|
||||
return d.Settings.TVR.FormatTopicState(d.Name)
|
||||
}
|
||||
|
||||
|
||||
func (d *Device) Program() (WeekProgram, error) {
|
||||
// return current device program if specified or default one
|
||||
prog_name := "default"
|
||||
@ -96,8 +93,7 @@ func (d *Device) Program() (WeekProgram, error) {
|
||||
return program, nil
|
||||
}
|
||||
|
||||
|
||||
func (d *Device) ProgramName() (string) {
|
||||
func (d *Device) ProgramName() string {
|
||||
prog_name := "default"
|
||||
if d.State.Program_name != "" {
|
||||
prog_name = d.State.Program_name
|
||||
@ -105,7 +101,6 @@ func (d *Device) ProgramName() (string) {
|
||||
return prog_name
|
||||
}
|
||||
|
||||
|
||||
func (d *Device) publishState(pubchan chan Message) error {
|
||||
|
||||
payload, err := json.Marshal(d.State)
|
||||
@ -113,7 +108,7 @@ func (d *Device) publishState(pubchan chan Message) error {
|
||||
return err
|
||||
}
|
||||
|
||||
pubchan <- Message {
|
||||
pubchan <- Message{
|
||||
Topic: d.StateTopic(),
|
||||
Payload: payload,
|
||||
Retain: true,
|
||||
@ -122,7 +117,6 @@ func (d *Device) publishState(pubchan chan Message) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
func (d *Device) SetSetpoint(value int, pubchan chan Message) error {
|
||||
topic, err := d.Settings.TVR.FormatTopic(d.Name)
|
||||
if err != nil {
|
||||
@ -142,7 +136,6 @@ func (d *Device) SetSetpoint(value int, pubchan chan Message) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
func (d *Device) SetState(log *zerolog.Logger, state DeviceState, pubchan chan Message) error {
|
||||
// If same state do nothing
|
||||
// else use checksetpoint for changing state
|
||||
@ -166,7 +159,6 @@ func (d *Device) SetState(log *zerolog.Logger, state DeviceState, pubchan chan M
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
func (d *Device) CheckSetpoint(log *zerolog.Logger, pubchan chan Message) error {
|
||||
change, err := d.update(log, pubchan)
|
||||
if err != nil {
|
||||
@ -182,7 +174,6 @@ func (d *Device) CheckSetpoint(log *zerolog.Logger, pubchan chan Message) error
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
func (d *Device) update(log *zerolog.Logger, pubchan chan Message) (bool, error) {
|
||||
// Handle all the update setpoint logic
|
||||
// push in pubChan a Message if setpoint need to be update
|
||||
@ -193,7 +184,7 @@ func (d *Device) update(log *zerolog.Logger, pubchan chan Message) (bool, error)
|
||||
Int("State.Setpoint", d.State.Setpoint).
|
||||
Str("State.Program_name", d.State.Program_name).
|
||||
Logger()
|
||||
log.Info().Msg("Check if setpoint need an update")
|
||||
log.Debug().Msg("check if setpoint need an update")
|
||||
|
||||
switch d.State.Mode {
|
||||
case "always":
|
||||
@ -213,7 +204,6 @@ func (d *Device) update(log *zerolog.Logger, pubchan chan Message) (bool, error)
|
||||
|
||||
}
|
||||
|
||||
|
||||
func (d *Device) onMessage(ctx context.Context, msg mqtt.Message) {
|
||||
log := zerolog.Ctx(ctx).With().
|
||||
Str("action", "device state receive").
|
||||
@ -239,7 +229,7 @@ func (d *Device) onMessage(ctx context.Context, msg mqtt.Message) {
|
||||
|
||||
r := x.First(obj)
|
||||
|
||||
if v, ok := r.(int64); ok{
|
||||
if v, ok := r.(int64); ok {
|
||||
d.CurrentSetpoint = int(v)
|
||||
} else {
|
||||
log.Error().Err(err).Interface("parsing payload", r).Msg("while parsing payload")
|
||||
@ -247,7 +237,6 @@ func (d *Device) onMessage(ctx context.Context, msg mqtt.Message) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
func (d *Device) handle_reset_state(log *zerolog.Logger, pubchan chan Message) (bool, error) {
|
||||
// called when need to fallback to program mode previous or default
|
||||
program, err := d.Program()
|
||||
@ -280,12 +269,11 @@ func (d *Device) handle_reset_state(log *zerolog.Logger, pubchan chan Message) (
|
||||
return true, nil
|
||||
}
|
||||
|
||||
|
||||
func (d *Device) handle_always(log *zerolog.Logger, pubchan chan Message) (bool, error) {
|
||||
// return true if change made
|
||||
|
||||
if d.State.Setpoint != d.CurrentSetpoint {
|
||||
if err:= d.SetSetpoint(d.State.Setpoint, pubchan); err != nil {
|
||||
if err := d.SetSetpoint(d.State.Setpoint, pubchan); err != nil {
|
||||
return false, err
|
||||
}
|
||||
return true, nil
|
||||
@ -324,7 +312,7 @@ func (d *Device) handle_until_next(log *zerolog.Logger, pubchan chan Message) (b
|
||||
}
|
||||
|
||||
next, err := program.NextTime(d.State.Time)
|
||||
if err!= nil {
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
|
@ -1,9 +1,10 @@
|
||||
package device
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"context"
|
||||
"github.com/eclipse/paho.mqtt.golang"
|
||||
"fmt"
|
||||
|
||||
mqtt "github.com/eclipse/paho.mqtt.golang"
|
||||
"github.com/rs/zerolog"
|
||||
)
|
||||
|
||||
|
@ -1,35 +1,35 @@
|
||||
package device
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"reflect"
|
||||
"testing"
|
||||
"time"
|
||||
"fmt"
|
||||
"reflect"
|
||||
|
||||
"github.com/rs/zerolog"
|
||||
"io/ioutil"
|
||||
)
|
||||
|
||||
// monday
|
||||
var test_time = time.Date(2022, time.October, 24, 0, 0, 0, 0, time.Local)
|
||||
|
||||
|
||||
var test_presets = []Preset{
|
||||
{Label: "default", Value: 17, Color: "#012a36"},
|
||||
{Label: "normal", Value: 19, Color: "#b6244f"},
|
||||
}
|
||||
|
||||
var test_setpoints = []Setpoint{
|
||||
{Start: 7*60, Preset_id: 1},
|
||||
{Start: 8*60, Preset_id: 0},
|
||||
{Start: 16*60, Preset_id: 1},
|
||||
{Start: 22*60, Preset_id: 0},
|
||||
{Start: 7 * 60, Preset_id: 1},
|
||||
{Start: 8 * 60, Preset_id: 0},
|
||||
{Start: 16 * 60, Preset_id: 1},
|
||||
{Start: 22 * 60, Preset_id: 0},
|
||||
}
|
||||
|
||||
var test_weekprogram = WeekProgram{
|
||||
Monday: test_setpoints,
|
||||
Thuesday: test_setpoints,
|
||||
Wednesday: test_setpoints,
|
||||
Thursday : test_setpoints,
|
||||
Thursday: test_setpoints,
|
||||
Friday: test_setpoints,
|
||||
Saturday: test_setpoints,
|
||||
Sunday: test_setpoints,
|
||||
@ -39,7 +39,7 @@ var test_programs = Programs{
|
||||
"default": test_weekprogram,
|
||||
}
|
||||
|
||||
var test_device = Device {
|
||||
var test_device = Device{
|
||||
Name: "valid",
|
||||
Settings: DeviceSettings{
|
||||
Programs: test_programs,
|
||||
@ -57,7 +57,7 @@ var test_device = Device {
|
||||
|
||||
func TestStateEquivalent(t *testing.T) {
|
||||
|
||||
var tests = []struct{
|
||||
var tests = []struct {
|
||||
state1 DeviceState
|
||||
state2 DeviceState
|
||||
want bool
|
||||
@ -86,7 +86,7 @@ func TestStateEquivalent(t *testing.T) {
|
||||
DeviceState{
|
||||
Mode: "program",
|
||||
Setpoint: 14,
|
||||
Time: test_time.Add(1*time.Minute),
|
||||
Time: test_time.Add(1 * time.Minute),
|
||||
Program_name: "default",
|
||||
},
|
||||
false,
|
||||
@ -186,14 +186,14 @@ func TestStateEquivalent(t *testing.T) {
|
||||
Mode: "until_time",
|
||||
Setpoint: 14,
|
||||
Time: test_time,
|
||||
Until_time: test_time.Add(1*time.Hour),
|
||||
Until_time: test_time.Add(1 * time.Hour),
|
||||
},
|
||||
DeviceState{
|
||||
Mode: "until_time",
|
||||
Setpoint: 14,
|
||||
Time: test_time,
|
||||
Program_name: "other",
|
||||
Until_time: test_time.Add(1*time.Hour),
|
||||
Until_time: test_time.Add(1 * time.Hour),
|
||||
},
|
||||
true,
|
||||
},
|
||||
@ -202,14 +202,14 @@ func TestStateEquivalent(t *testing.T) {
|
||||
Mode: "until_time",
|
||||
Setpoint: 14,
|
||||
Time: test_time,
|
||||
Until_time: test_time.Add(1*time.Hour),
|
||||
Until_time: test_time.Add(1 * time.Hour),
|
||||
},
|
||||
DeviceState{
|
||||
Mode: "until_time",
|
||||
Setpoint: 13,
|
||||
Time: test_time,
|
||||
Program_name: "other",
|
||||
Until_time: test_time.Add(1*time.Hour),
|
||||
Until_time: test_time.Add(1 * time.Hour),
|
||||
},
|
||||
false,
|
||||
},
|
||||
@ -218,20 +218,20 @@ func TestStateEquivalent(t *testing.T) {
|
||||
Mode: "until_time",
|
||||
Setpoint: 14,
|
||||
Time: test_time,
|
||||
Until_time: test_time.Add(1*time.Hour),
|
||||
Until_time: test_time.Add(1 * time.Hour),
|
||||
},
|
||||
DeviceState{
|
||||
Mode: "until_time",
|
||||
Setpoint: 14,
|
||||
Time: test_time,
|
||||
Program_name: "other",
|
||||
Until_time: test_time.Add(2*time.Hour),
|
||||
Until_time: test_time.Add(2 * time.Hour),
|
||||
},
|
||||
false,
|
||||
},
|
||||
}
|
||||
for i, tt := range tests {
|
||||
testname := fmt.Sprintf("%d", i )
|
||||
testname := fmt.Sprintf("%d", i)
|
||||
t.Run(testname, func(t *testing.T) {
|
||||
r := tt.state1.Equivalent(tt.state2)
|
||||
if r != tt.want {
|
||||
@ -241,7 +241,6 @@ func TestStateEquivalent(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func TestStateTopic(t *testing.T) {
|
||||
topic := test_device.StateTopic()
|
||||
if topic != "heater/valid/state" {
|
||||
@ -270,7 +269,7 @@ func TestProgram(t *testing.T) {
|
||||
Monday: test_setpoints,
|
||||
Thuesday: test_setpoints,
|
||||
Wednesday: test_setpoints,
|
||||
Thursday : test_setpoints,
|
||||
Thursday: test_setpoints,
|
||||
Friday: test_setpoints,
|
||||
Saturday: test_setpoints,
|
||||
Sunday: test_setpoints,
|
||||
@ -297,20 +296,19 @@ func TestProgram(t *testing.T) {
|
||||
{"case 3 program confort no defined", case3_device, WeekProgram{}, Error("device valid don't have confort program")},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
testname := fmt.Sprintf("%s", tt.name )
|
||||
testname := fmt.Sprintf("%s", tt.name)
|
||||
t.Run(testname, func(t *testing.T) {
|
||||
prog, err := tt.device.Program()
|
||||
if err != tt.err {
|
||||
t.Errorf("got %s, want %s", err, tt.err)
|
||||
}
|
||||
if !reflect.DeepEqual(prog,tt.result) {
|
||||
if !reflect.DeepEqual(prog, tt.result) {
|
||||
t.Errorf("got %v, want %v", prog, tt.result)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func TestUpdate(t *testing.T) {
|
||||
// device 1: currentSetpoint 0 program, not specified expect default
|
||||
// device 2: currentSetpoint 0 program, unknown one, expect error
|
||||
@ -319,7 +317,6 @@ func TestUpdate(t *testing.T) {
|
||||
// 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
|
||||
}
|
||||
@ -351,7 +348,7 @@ func TestUpdate(t *testing.T) {
|
||||
Mode: "until_time",
|
||||
Setpoint: 22,
|
||||
Time: timeNow(),
|
||||
Until_time: timeNow().Add(2*time.Hour),
|
||||
Until_time: timeNow().Add(2 * time.Hour),
|
||||
}
|
||||
|
||||
device5 := test_device
|
||||
@ -360,8 +357,8 @@ func TestUpdate(t *testing.T) {
|
||||
device5.State = DeviceState{
|
||||
Mode: "until_time",
|
||||
Setpoint: 22,
|
||||
Time: timeNow().Add(-2*time.Hour),
|
||||
Until_time: timeNow().Add(-1*time.Minute),
|
||||
Time: timeNow().Add(-2 * time.Hour),
|
||||
Until_time: timeNow().Add(-1 * time.Minute),
|
||||
}
|
||||
|
||||
device6 := test_device
|
||||
@ -373,8 +370,7 @@ func TestUpdate(t *testing.T) {
|
||||
Time: timeNow(),
|
||||
}
|
||||
|
||||
|
||||
var tests = []struct{
|
||||
var tests = []struct {
|
||||
getTime func() time.Time
|
||||
device Device
|
||||
want []Message
|
||||
@ -382,34 +378,34 @@ func TestUpdate(t *testing.T) {
|
||||
err error
|
||||
}{
|
||||
{timeNow, device1, []Message{
|
||||
Message{
|
||||
{
|
||||
Payload: []byte("{\"current_heating_setpoint\": 17}"),
|
||||
Topic: "zigbee2mqtt/TVR/1/set",
|
||||
Retain: false,
|
||||
},
|
||||
}, true, nil} ,
|
||||
}, true, nil},
|
||||
{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} ,
|
||||
{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{
|
||||
}, 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{
|
||||
{
|
||||
Payload: []byte("{\"current_heating_setpoint\": 19}"),
|
||||
Topic: "zigbee2mqtt/TVR/6/set",
|
||||
Retain: false,
|
||||
},
|
||||
}, true, nil} ,
|
||||
}, true, nil},
|
||||
}
|
||||
|
||||
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) {
|
||||
|
||||
timeNow = tt.getTime
|
||||
@ -433,7 +429,7 @@ func TestUpdate(t *testing.T) {
|
||||
result = append(result, msg)
|
||||
}
|
||||
|
||||
err, ok := <- errchan
|
||||
err, ok := <-errchan
|
||||
if !ok {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@ -442,7 +438,7 @@ func TestUpdate(t *testing.T) {
|
||||
t.Errorf("got %s, want %s", err, tt.err)
|
||||
}
|
||||
|
||||
change, ok := <- changechan
|
||||
change, ok := <-changechan
|
||||
if !ok {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@ -451,7 +447,7 @@ func TestUpdate(t *testing.T) {
|
||||
t.Errorf("got %s, want %s", err, tt.err)
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(result,tt.want) {
|
||||
if !reflect.DeepEqual(result, tt.want) {
|
||||
t.Errorf("got %v, want %v", result, tt.want)
|
||||
}
|
||||
})
|
||||
|
@ -1,10 +1,10 @@
|
||||
package device
|
||||
|
||||
import (
|
||||
"time"
|
||||
"bytes"
|
||||
"text/template"
|
||||
"fmt"
|
||||
"text/template"
|
||||
"time"
|
||||
)
|
||||
|
||||
type DayOfWeek int
|
||||
@ -13,22 +13,22 @@ func (d DayOfWeek) Next() DayOfWeek {
|
||||
if d == Sunday {
|
||||
return Monday
|
||||
}
|
||||
return d+1
|
||||
return d + 1
|
||||
}
|
||||
|
||||
func (d DayOfWeek) Previous() DayOfWeek {
|
||||
if d == Monday {
|
||||
return Sunday
|
||||
}
|
||||
return d-1
|
||||
return d - 1
|
||||
}
|
||||
|
||||
func (d DayOfWeek) DaysBetween(n DayOfWeek) int {
|
||||
var between int
|
||||
if (n < d) {
|
||||
if n < d {
|
||||
between = 7 - int(d-n)
|
||||
} else {
|
||||
between = int(n-d)
|
||||
between = int(n - d)
|
||||
}
|
||||
return between
|
||||
}
|
||||
@ -45,11 +45,11 @@ const (
|
||||
|
||||
func WeekDayEnToFr(weekday time.Weekday) DayOfWeek {
|
||||
// translate weekday to french week, start by Monday
|
||||
return map[time.Weekday]DayOfWeek {
|
||||
time.Monday : Monday,
|
||||
time.Tuesday : Thuesday,
|
||||
return map[time.Weekday]DayOfWeek{
|
||||
time.Monday: Monday,
|
||||
time.Tuesday: Thuesday,
|
||||
time.Wednesday: Wednesday,
|
||||
time.Thursday : Thursday,
|
||||
time.Thursday: Thursday,
|
||||
time.Friday: Friday,
|
||||
time.Saturday: Saturday,
|
||||
time.Sunday: Sunday,
|
||||
@ -77,13 +77,12 @@ type Setpoint struct {
|
||||
|
||||
func (s Setpoint) Value(presets []Preset) (int, error) {
|
||||
//TODO need test
|
||||
if len(presets) < s.Preset_id + 1 {
|
||||
if len(presets) < s.Preset_id+1 {
|
||||
return 0, Error(fmt.Sprintf("preset id %d not found", s.Preset_id))
|
||||
}
|
||||
return presets[s.Preset_id].Value, nil
|
||||
}
|
||||
|
||||
|
||||
type WeekProgram map[DayOfWeek][]Setpoint
|
||||
|
||||
func (p WeekProgram) Current() Setpoint {
|
||||
@ -109,7 +108,7 @@ func (p WeekProgram) NextTime(t time.Time) (time.Time, error) {
|
||||
daytime := daytime(t)
|
||||
|
||||
// Recursive func to find setpoint on weekday
|
||||
get := func (weekday DayOfWeek, daytime int) (Setpoint, bool) {
|
||||
get := func(weekday DayOfWeek, daytime int) (Setpoint, bool) {
|
||||
for _, sp := range p[weekday] {
|
||||
if daytime <= sp.Start {
|
||||
return sp, true
|
||||
@ -123,19 +122,19 @@ func (p WeekProgram) NextTime(t time.Time) (time.Time, error) {
|
||||
if setpoint, ok := get(weekday, daytime); ok {
|
||||
next := time.Date(t.Year(),
|
||||
t.Month(),
|
||||
t.Day() + startweekday.DaysBetween(weekday),
|
||||
t.Day()+startweekday.DaysBetween(weekday),
|
||||
0, 0, 0, 0,
|
||||
time.Local)
|
||||
|
||||
next = next.Add(
|
||||
time.Duration( (setpoint.Start) * int(time.Minute) ))
|
||||
time.Duration((setpoint.Start) * int(time.Minute)))
|
||||
return next, nil
|
||||
}
|
||||
|
||||
weekday = weekday.Next()
|
||||
daytime = 0
|
||||
if weekday == startweekday {
|
||||
return time.Time{}, fmt.Errorf("Shouldn't happen no setpoint found over the week")
|
||||
return time.Time{}, Error("shouldn't happen no setpoint found over the week")
|
||||
}
|
||||
}
|
||||
|
||||
@ -222,17 +221,17 @@ var DefaultPresets = []Preset{
|
||||
}
|
||||
|
||||
var defaultSetpoints = []Setpoint{
|
||||
{Start: 7*60, Preset_id: 1},
|
||||
{Start: 8*60, Preset_id: 0},
|
||||
{Start: 16*60, Preset_id: 1},
|
||||
{Start: 22*60, Preset_id: 0},
|
||||
{Start: 7 * 60, Preset_id: 1},
|
||||
{Start: 8 * 60, Preset_id: 0},
|
||||
{Start: 16 * 60, Preset_id: 1},
|
||||
{Start: 22 * 60, Preset_id: 0},
|
||||
}
|
||||
|
||||
var DefaultWeekProgram = WeekProgram{
|
||||
Monday: defaultSetpoints,
|
||||
Thuesday: defaultSetpoints,
|
||||
Wednesday: defaultSetpoints,
|
||||
Thursday : defaultSetpoints,
|
||||
Thursday: defaultSetpoints,
|
||||
Friday: defaultSetpoints,
|
||||
Saturday: defaultSetpoints,
|
||||
Sunday: defaultSetpoints,
|
||||
@ -242,11 +241,11 @@ var DefaultPrograms = Programs{
|
||||
"default": DefaultWeekProgram,
|
||||
}
|
||||
|
||||
var DefaultTVRSettings = TVRSettings {
|
||||
Setpoint_topic : "zigbee2mqtt/TVR/{{.Device}}/set",
|
||||
Setpoint_payload : "{\"current_heating_setpoint\": {{.Setpoint}}}",
|
||||
Setpoint_state_topic : "zigbee2mqtt/TVR/{{.Device}}",
|
||||
Setpoint_state_jp : "$.current_heating_setpoint",
|
||||
var DefaultTVRSettings = TVRSettings{
|
||||
Setpoint_topic: "zigbee2mqtt/TVR/{{.Device}}/set",
|
||||
Setpoint_payload: "{\"current_heating_setpoint\": {{.Setpoint}}}",
|
||||
Setpoint_state_topic: "zigbee2mqtt/TVR/{{.Device}}",
|
||||
Setpoint_state_jp: "$.current_heating_setpoint",
|
||||
}
|
||||
|
||||
var DefaultDeviceSettings = DeviceSettings{
|
||||
|
@ -1,25 +1,25 @@
|
||||
package device
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
"time"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
func TestDaysBetween(t *testing.T) {
|
||||
var tests = []struct{
|
||||
var tests = []struct {
|
||||
day1 DayOfWeek
|
||||
day2 DayOfWeek
|
||||
want int
|
||||
}{
|
||||
{ Monday, Thuesday, 1 },
|
||||
{ Thuesday, Monday, 6 },
|
||||
{ Sunday, Monday, 1 },
|
||||
{ Sunday, Thuesday, 2 },
|
||||
{ Friday, Friday, 0 },
|
||||
{Monday, Thuesday, 1},
|
||||
{Thuesday, Monday, 6},
|
||||
{Sunday, Monday, 1},
|
||||
{Sunday, Thuesday, 2},
|
||||
{Friday, Friday, 0},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
testname := fmt.Sprintf("Days between %d and %d", tt.day1, tt.day2 )
|
||||
testname := fmt.Sprintf("Days between %d and %d", tt.day1, tt.day2)
|
||||
t.Run(testname, func(t *testing.T) {
|
||||
between := tt.day1.DaysBetween(tt.day2)
|
||||
if between != tt.want {
|
||||
@ -29,26 +29,24 @@ func TestDaysBetween(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func TestNextTime(t *testing.T) {
|
||||
|
||||
defaultSetpoints := []Setpoint{
|
||||
{Start: 7*60, Preset_id: 1},
|
||||
{Start: 8*60, Preset_id: 0},
|
||||
{Start: 16*60, Preset_id: 1},
|
||||
{Start: 22*60, Preset_id: 0},
|
||||
{Start: 7 * 60, Preset_id: 1},
|
||||
{Start: 8 * 60, Preset_id: 0},
|
||||
{Start: 16 * 60, Preset_id: 1},
|
||||
{Start: 22 * 60, Preset_id: 0},
|
||||
}
|
||||
|
||||
zeroSetpoints := []Setpoint{
|
||||
{Start: 0, Preset_id: 0},
|
||||
}
|
||||
|
||||
|
||||
default_program := WeekProgram{
|
||||
Monday: defaultSetpoints,
|
||||
Thuesday: defaultSetpoints,
|
||||
Wednesday: defaultSetpoints,
|
||||
Thursday : defaultSetpoints,
|
||||
Thursday: defaultSetpoints,
|
||||
Friday: defaultSetpoints,
|
||||
Saturday: defaultSetpoints,
|
||||
Sunday: defaultSetpoints,
|
||||
@ -58,14 +56,13 @@ func TestNextTime(t *testing.T) {
|
||||
Monday: zeroSetpoints,
|
||||
Thuesday: zeroSetpoints,
|
||||
Wednesday: zeroSetpoints,
|
||||
Thursday : zeroSetpoints,
|
||||
Thursday: zeroSetpoints,
|
||||
Friday: zeroSetpoints,
|
||||
Saturday: zeroSetpoints,
|
||||
Sunday: zeroSetpoints,
|
||||
}
|
||||
|
||||
|
||||
var tests = []struct{
|
||||
var tests = []struct {
|
||||
prog WeekProgram
|
||||
time time.Time
|
||||
want time.Time
|
||||
@ -92,7 +89,7 @@ func TestNextTime(t *testing.T) {
|
||||
},
|
||||
}
|
||||
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) {
|
||||
next, err := tt.prog.NextTime(tt.time)
|
||||
if err != nil {
|
||||
|
Loading…
x
Reference in New Issue
Block a user