Improve device API and test CheckSetpoint
This commit is contained in:
parent
b07e2829c6
commit
86175870b0
@ -12,6 +12,15 @@ import (
|
|||||||
// "reflect"
|
// "reflect"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var timeNow = func() time.Time {
|
||||||
|
return time.Now()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
type Error string
|
||||||
|
func (e Error) Error() string { return string(e) }
|
||||||
|
|
||||||
type DeviceState struct {
|
type DeviceState struct {
|
||||||
Mode string `json:"mode"`
|
Mode string `json:"mode"`
|
||||||
Setpoint int `json:"setpoint"`
|
Setpoint int `json:"setpoint"`
|
||||||
@ -51,113 +60,34 @@ func (d *Device) StateTopic() string {
|
|||||||
return fmt.Sprintf("heater/%s/state", d.Name)
|
return fmt.Sprintf("heater/%s/state", d.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Device) CheckSetpoint(logger *zerolog.Logger, pubchan chan Message) error {
|
func (d Device) ListenTopic() (string, error) {
|
||||||
// Handle all the update setpoint logic
|
return d.Settings.TVR.FormatTopicState(d.Name)
|
||||||
// push in pubChan a Message if setpoint need to be update
|
|
||||||
log := logger.With().
|
|
||||||
Str("device", d.Name).
|
|
||||||
Int("current_setpoint", d.CurrentSetpoint).
|
|
||||||
Str("State.Mode", d.State.Mode).
|
|
||||||
Int("State.Setpoint", d.State.Setpoint).
|
|
||||||
Str("State.Program_name", d.State.Program_name).
|
|
||||||
Logger()
|
|
||||||
log.Info().Msg("Check if setpoint need an update")
|
|
||||||
|
|
||||||
switch d.State.Mode {
|
|
||||||
case "always":
|
|
||||||
log.Info().Msg("Use always")
|
|
||||||
|
|
||||||
case "until_time":
|
|
||||||
log.Info().Msg("Use until_time")
|
|
||||||
if d.State.Until_time.Before(time.Now()) {
|
|
||||||
log.Info().Time("until_time", d.State.Until_time).
|
|
||||||
Msg("until_time passed, reset")
|
|
||||||
return d.setProgAndReset(&log, pubchan)
|
|
||||||
}
|
|
||||||
|
|
||||||
case "until_next":
|
|
||||||
log.Info().Msg("Use until_next")
|
|
||||||
|
|
||||||
var prog string = "default"
|
|
||||||
if d.State.Program_name != "" {
|
|
||||||
prog = d.State.Program_name
|
|
||||||
}
|
|
||||||
program, ok := d.Settings.Programs[prog]
|
|
||||||
if !ok {
|
|
||||||
return fmt.Errorf("program not found")
|
|
||||||
}
|
|
||||||
next, err := program.NextTime(d.State.Time)
|
|
||||||
if err!= nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if time.Now().After(next) {
|
|
||||||
// force current program
|
|
||||||
// reset state
|
|
||||||
log.Info().Time("now", time.Now()).Time("next", next).Msg("until_next expired")
|
|
||||||
return d.setProgAndReset(&log, pubchan)
|
|
||||||
}
|
|
||||||
case "program":
|
|
||||||
log.Info().Msg("Use program mode")
|
|
||||||
if d.State.Setpoint == 0 {
|
|
||||||
//in case of new program mode
|
|
||||||
var prog string = "default"
|
|
||||||
if d.State.Program_name != "" {
|
|
||||||
prog = d.State.Program_name
|
|
||||||
}
|
|
||||||
value, err := d.setpointValueProg(prog)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
d.State.Setpoint = value
|
|
||||||
d.PublishState(d.State, pubchan)
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
log.Info().Msg("Use default mode")
|
|
||||||
return d.setProgAndReset(&log, pubchan)
|
|
||||||
}
|
|
||||||
|
|
||||||
if d.State.Setpoint != d.CurrentSetpoint {
|
|
||||||
log.Warn().Msg("Need setpoint update")
|
|
||||||
return d.publishSetpoint(d.State.Setpoint, pubchan)
|
|
||||||
} else {
|
|
||||||
log.Warn().Msg("No setpoint update")
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Device) setProgAndReset(logger *zerolog.Logger, pubchan chan Message) error {
|
func (d *Device) Program() (WeekProgram, error) {
|
||||||
|
// return current device program if specified or default one
|
||||||
prog_name := "default"
|
prog_name := "default"
|
||||||
if d.State.Program_name != "" {
|
if d.State.Program_name != "" {
|
||||||
prog_name = d.State.Program_name
|
prog_name = d.State.Program_name
|
||||||
}
|
}
|
||||||
log := logger.With().Str("program", prog_name).Logger()
|
|
||||||
|
|
||||||
value, err := d.setpointValueProg(prog_name)
|
program, ok := d.Settings.Programs[prog_name]
|
||||||
if err != nil {
|
if !ok {
|
||||||
return err
|
return WeekProgram{}, Error(fmt.Sprintf("device %s don't have %s program", d.Name, prog_name))
|
||||||
}
|
|
||||||
log = log.With().Int("futur_setpoint", value).Logger()
|
|
||||||
|
|
||||||
if d.CurrentSetpoint != value {
|
|
||||||
log.Warn().Msg("publish setpoint update")
|
|
||||||
err = d.publishSetpoint(value, pubchan)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
log.Warn().Msg("no setpoint update")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
state := DeviceState{
|
return program, nil
|
||||||
Setpoint: value,
|
}
|
||||||
Mode: "program",
|
|
||||||
Program_name: prog_name,
|
|
||||||
Time: time.Now(),
|
|
||||||
}
|
|
||||||
|
|
||||||
d.State = state
|
func (d *Device) ProgramName() (string) {
|
||||||
|
prog_name := "default"
|
||||||
|
if d.State.Program_name != "" {
|
||||||
|
prog_name = d.State.Program_name
|
||||||
|
}
|
||||||
|
return prog_name
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *Device) SetState(state DeviceState, pubchan chan Message) error {
|
||||||
|
|
||||||
payload, err := json.Marshal(state)
|
payload, err := json.Marshal(state)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -169,10 +99,13 @@ func (d *Device) setProgAndReset(logger *zerolog.Logger, pubchan chan Message) e
|
|||||||
Payload: payload,
|
Payload: payload,
|
||||||
Retain: true,
|
Retain: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
d.State = state
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Device) publishSetpoint(value int, pubchan chan Message) error {
|
func (d *Device) SetSetpoint(value int, pubchan chan Message) error {
|
||||||
topic, err := d.Settings.TVR.FormatTopic(d.Name)
|
topic, err := d.Settings.TVR.FormatTopic(d.Name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -191,22 +124,70 @@ func (d *Device) publishSetpoint(value int, pubchan chan Message) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Device) PublishState(state DeviceState, pubchan chan Message) error {
|
|
||||||
payload, err := json.Marshal(state)
|
func (d *Device) CheckSetpoint(logger *zerolog.Logger, pubchan chan Message) error {
|
||||||
|
// Handle all the update setpoint logic
|
||||||
|
// push in pubChan a Message if setpoint need to be update
|
||||||
|
log := logger.With().
|
||||||
|
Str("device", d.Name).
|
||||||
|
Int("current_setpoint", d.CurrentSetpoint).
|
||||||
|
Str("State.Mode", d.State.Mode).
|
||||||
|
Int("State.Setpoint", d.State.Setpoint).
|
||||||
|
Str("State.Program_name", d.State.Program_name).
|
||||||
|
Logger()
|
||||||
|
log.Info().Msg("Check if setpoint need an update")
|
||||||
|
|
||||||
|
switch d.State.Mode {
|
||||||
|
case "always":
|
||||||
|
return d.handle_always(&log, pubchan)
|
||||||
|
|
||||||
|
case "until_time":
|
||||||
|
return d.handle_until_time(&log, pubchan)
|
||||||
|
|
||||||
|
case "until_next":
|
||||||
|
return d.handle_until_next(&log, pubchan)
|
||||||
|
case "program":
|
||||||
|
return d.handle_program(&log, pubchan)
|
||||||
|
default:
|
||||||
|
log.Info().Msg("Use default mode")
|
||||||
|
return d.setProgAndReset(&log, pubchan)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *Device) setProgAndReset(log *zerolog.Logger, pubchan chan Message) error {
|
||||||
|
program, err := d.Program()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
pubchan <- Message{
|
|
||||||
Topic: d.StateTopic(),
|
current_setpoint := program.Current()
|
||||||
Payload: payload,
|
|
||||||
Retain: true,
|
value, err := current_setpoint.Value(d.Settings.Presets)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
|
||||||
|
if d.CurrentSetpoint != value {
|
||||||
|
log.Info().Msg("publish setpoint update")
|
||||||
|
err = d.SetSetpoint(value, pubchan)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log.Info().Msg("no setpoint update")
|
||||||
|
}
|
||||||
|
|
||||||
|
state := DeviceState{
|
||||||
|
Setpoint: value,
|
||||||
|
Mode: "program",
|
||||||
|
Program_name: d.ProgramName(),
|
||||||
|
Time: timeNow(),
|
||||||
|
}
|
||||||
|
|
||||||
|
return d.SetState(state, pubchan)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d Device) ListenTopic() (string, error) {
|
|
||||||
return d.Settings.TVR.FormatTopicState(d.Name)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *Device) onMessage(ctx context.Context, msg mqtt.Message) {
|
func (d *Device) onMessage(ctx context.Context, msg mqtt.Message) {
|
||||||
log := zerolog.Ctx(ctx).With().
|
log := zerolog.Ctx(ctx).With().
|
||||||
@ -241,30 +222,83 @@ func (d *Device) onMessage(ctx context.Context, msg mqtt.Message) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Device) programSetpoint(prog_name string) (Setpoint, error) {
|
|
||||||
program, ok := d.Settings.Programs[prog_name]
|
func (d *Device) handle_always(log *zerolog.Logger, pubchan chan Message) error {
|
||||||
if !ok {
|
if d.State.Setpoint != d.CurrentSetpoint {
|
||||||
return Setpoint{}, fmt.Errorf("device %s don't have %s program", d.Name, prog_name)
|
return d.SetSetpoint(d.State.Setpoint, pubchan)
|
||||||
}
|
}
|
||||||
setpoint := program.Current()
|
|
||||||
return setpoint, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Device) setpointValue(setpoint Setpoint) (int, error) {
|
func (d *Device) handle_until_time(log *zerolog.Logger, pubchan chan Message) error {
|
||||||
if len(d.Settings.Presets) < setpoint.Preset_id + 1 {
|
*log = log.With().Time("until_time", d.State.Until_time).Logger()
|
||||||
return 0, fmt.Errorf("Preset id %d didn't found", setpoint.Preset_id)
|
|
||||||
|
if d.State.Until_time.Before(timeNow()) {
|
||||||
|
log.Info().Msg("until_time passed, reset")
|
||||||
|
return d.setProgAndReset(log, pubchan)
|
||||||
}
|
}
|
||||||
return d.Settings.Presets[setpoint.Preset_id].Value, nil
|
|
||||||
|
if d.State.Setpoint != d.CurrentSetpoint {
|
||||||
|
log.Info().Msg("need setpoint update")
|
||||||
|
return d.SetSetpoint(d.State.Setpoint, pubchan)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Device) setpointValueProg(prog_name string) (int, error) {
|
func (d *Device) handle_until_next(log *zerolog.Logger, pubchan chan Message) error {
|
||||||
setpoint, err := d.programSetpoint(prog_name)
|
*log = log.With().Time("until_next", d.State.Time).Logger()
|
||||||
if err != nil{
|
|
||||||
return 0, err
|
program, err := d.Program()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
val, err := d.setpointValue(setpoint)
|
|
||||||
if err != nil{
|
next, err := program.NextTime(d.State.Time)
|
||||||
return 0, err
|
if err!= nil {
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
return val, nil
|
|
||||||
|
if timeNow().After(next) {
|
||||||
|
// force current program
|
||||||
|
// reset state
|
||||||
|
log.Info().Time("now", timeNow()).Time("next", next).Msg("until_next expired")
|
||||||
|
return d.setProgAndReset(log, pubchan)
|
||||||
|
}
|
||||||
|
|
||||||
|
if d.State.Setpoint != d.CurrentSetpoint {
|
||||||
|
log.Info().Msg("need setpoint update")
|
||||||
|
return d.SetSetpoint(d.State.Setpoint, pubchan)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *Device) handle_program(log *zerolog.Logger, pubchan chan Message) error {
|
||||||
|
*log = log.With().Str("program", d.State.Program_name).Logger()
|
||||||
|
|
||||||
|
program, err := d.Program()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
current_setpoint := program.Current()
|
||||||
|
|
||||||
|
value, err := current_setpoint.Value(d.Settings.Presets)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if d.CurrentSetpoint != value {
|
||||||
|
log.Info().Msg("publish setpoint update")
|
||||||
|
err = d.SetSetpoint(value, pubchan)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log.Info().Msg("no setpoint update")
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -2,23 +2,183 @@ package device
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
"time"
|
||||||
|
"fmt"
|
||||||
|
"reflect"
|
||||||
|
"github.com/rs/zerolog"
|
||||||
|
"io/ioutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
var goodDefaultDevice = Device {
|
// 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},
|
||||||
|
}
|
||||||
|
|
||||||
|
var test_weekprogram = WeekProgram{
|
||||||
|
Monday: test_setpoints,
|
||||||
|
Thuesday: test_setpoints,
|
||||||
|
Wednesday: test_setpoints,
|
||||||
|
Thursday : test_setpoints,
|
||||||
|
Friday: test_setpoints,
|
||||||
|
Saturday: test_setpoints,
|
||||||
|
Sunday: test_setpoints,
|
||||||
|
}
|
||||||
|
|
||||||
|
var test_programs = Programs{
|
||||||
|
"default": test_weekprogram,
|
||||||
|
}
|
||||||
|
|
||||||
|
var test_device = Device {
|
||||||
Name: "valid",
|
Name: "valid",
|
||||||
Settings: DefaultDeviceSettings,
|
Settings: DeviceSettings{
|
||||||
|
Programs: test_programs,
|
||||||
|
Presets: test_presets,
|
||||||
|
TVR: DefaultTVRSettings,
|
||||||
|
},
|
||||||
CurrentSetpoint: 0,
|
CurrentSetpoint: 0,
|
||||||
State: DeviceState{},
|
State: DeviceState{
|
||||||
|
Mode: "program",
|
||||||
|
Setpoint: 14,
|
||||||
|
Time: test_time,
|
||||||
|
Program_name: "default",
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func TestStateTopic(t *testing.T) {
|
func TestStateTopic(t *testing.T) {
|
||||||
topic := goodDefaultDevice.StateTopic()
|
topic := test_device.StateTopic()
|
||||||
if topic != "heater/valid/state" {
|
if topic != "heater/valid/state" {
|
||||||
t.Errorf("Got %s; want heater/valid/state", topic)
|
t.Errorf("Got %s; want heater/valid/state", topic)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestProgram(t *testing.T) {
|
||||||
|
//case 1: no program set in state return default
|
||||||
|
case1_device := test_device
|
||||||
|
case1_device.State.Program_name = ""
|
||||||
|
|
||||||
|
//case 2: program set "confort" must return it
|
||||||
|
var test_confort_weekprogram = WeekProgram{
|
||||||
|
Monday: test_setpoints,
|
||||||
|
Thuesday: test_setpoints,
|
||||||
|
Wednesday: test_setpoints,
|
||||||
|
Thursday : test_setpoints,
|
||||||
|
Friday: test_setpoints,
|
||||||
|
Saturday: test_setpoints,
|
||||||
|
Sunday: test_setpoints,
|
||||||
|
}
|
||||||
|
case2_device := test_device
|
||||||
|
case2_device.Settings.Programs = Programs{
|
||||||
|
"default": test_weekprogram,
|
||||||
|
"confort": test_confort_weekprogram,
|
||||||
|
}
|
||||||
|
case2_device.State.Program_name = "confort"
|
||||||
|
|
||||||
|
//case 3: program set "confort" but not exist
|
||||||
|
case3_device := test_device
|
||||||
|
case3_device.State.Program_name = "confort"
|
||||||
|
|
||||||
|
var tests = []struct {
|
||||||
|
name string
|
||||||
|
device Device
|
||||||
|
result WeekProgram
|
||||||
|
err error
|
||||||
|
}{
|
||||||
|
{"case 1 no program set use default", case1_device, DefaultWeekProgram, nil},
|
||||||
|
{"case 2 program confort", case2_device, test_confort_weekprogram, nil},
|
||||||
|
{"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 )
|
||||||
|
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) {
|
||||||
|
t.Errorf("got %v, want %v", prog, tt.result)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
func TestCheckSetpoint(t *testing.T) {
|
func TestCheckSetpoint(t *testing.T) {
|
||||||
|
timeNow = func() time.Time {
|
||||||
|
return test_time
|
||||||
|
}
|
||||||
|
|
||||||
|
device1 := test_device
|
||||||
|
device1.Name = "1"
|
||||||
|
device1.State = DeviceState{
|
||||||
|
Mode: "program",
|
||||||
|
Setpoint: 0,
|
||||||
|
Time: test_time,
|
||||||
|
Program_name: "",
|
||||||
|
}
|
||||||
|
|
||||||
|
device2 := test_device
|
||||||
|
device2.Name = "2"
|
||||||
|
device2.State.Program_name = "unknown"
|
||||||
|
|
||||||
|
var tests = []struct{
|
||||||
|
device Device
|
||||||
|
want []Message
|
||||||
|
err error
|
||||||
|
}{
|
||||||
|
{device1, []Message{Message{
|
||||||
|
Payload: []byte("{\"current_heating_setpoint\": 17}"),
|
||||||
|
Topic: "zigbee2mqtt/TVR/1/set",
|
||||||
|
Retain: false,
|
||||||
|
}}, nil} ,
|
||||||
|
{device2, []Message{}, Error("device 2 don't have unknown program")},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
testname := fmt.Sprintf("%s", tt.device.Name )
|
||||||
|
t.Run(testname, func(t *testing.T) {
|
||||||
|
|
||||||
|
result := []Message{}
|
||||||
|
|
||||||
|
rchan := make(chan Message, 10)
|
||||||
|
errchan := make(chan error, 1)
|
||||||
|
|
||||||
|
go func(result chan Message, errchan chan error) {
|
||||||
|
logger := zerolog.New(ioutil.Discard).With().Timestamp().Logger()
|
||||||
|
errchan <- tt.device.CheckSetpoint(&logger, result)
|
||||||
|
close(rchan)
|
||||||
|
close(errchan)
|
||||||
|
}(rchan, errchan)
|
||||||
|
|
||||||
|
for msg := range rchan {
|
||||||
|
result = append(result, msg)
|
||||||
|
}
|
||||||
|
|
||||||
|
err, ok := <- errchan
|
||||||
|
if !ok {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err != tt.err {
|
||||||
|
t.Errorf("got %s, want %s", err, tt.err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !reflect.DeepEqual(result,tt.want) {
|
||||||
|
t.Errorf("got %v, want %v", result, tt.want)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -75,13 +75,21 @@ type Setpoint struct {
|
|||||||
Preset_id int `json:"preset_id"`
|
Preset_id int `json:"preset_id"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s Setpoint) Value(presets []Preset) (int, error) {
|
||||||
|
//TODO need test
|
||||||
|
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
|
type WeekProgram map[DayOfWeek][]Setpoint
|
||||||
|
|
||||||
func (p WeekProgram) Current() Setpoint {
|
func (p WeekProgram) Current() Setpoint {
|
||||||
|
// TODO: need test
|
||||||
// return current Setpoint
|
// return current Setpoint
|
||||||
now := time.Now()
|
now := timeNow()
|
||||||
weekday := weekday(now)
|
weekday := weekday(now)
|
||||||
daytime := daytime(now)
|
daytime := daytime(now)
|
||||||
setpoint := Setpoint{}
|
setpoint := Setpoint{}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user