TVR: Add valve state and local temperature
This commit is contained in:
parent
f5e9d460c8
commit
4174d627fb
1
main.go
1
main.go
@ -65,6 +65,7 @@ func (app *App) subscribe(
|
|||||||
) context.CancelFunc {
|
) context.CancelFunc {
|
||||||
|
|
||||||
ctx, cancelFunc := context.WithCancel(app.ctx)
|
ctx, cancelFunc := context.WithCancel(app.ctx)
|
||||||
|
ctx = context.WithValue(ctx, "pubchan", app.PubChan)
|
||||||
|
|
||||||
log := zerolog.Ctx(ctx)
|
log := zerolog.Ctx(ctx)
|
||||||
|
|
||||||
|
@ -7,7 +7,6 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"git.quimbo.fr/nicolas/mqtt"
|
"git.quimbo.fr/nicolas/mqtt"
|
||||||
"github.com/ohler55/ojg/jp"
|
|
||||||
"github.com/ohler55/ojg/oj"
|
"github.com/ohler55/ojg/oj"
|
||||||
"github.com/rs/zerolog"
|
"github.com/rs/zerolog"
|
||||||
// "reflect"
|
// "reflect"
|
||||||
@ -27,6 +26,8 @@ type DeviceState struct {
|
|||||||
Time time.Time `json:"time"`
|
Time time.Time `json:"time"`
|
||||||
ProgramName string `json:"program_name"`
|
ProgramName string `json:"program_name"`
|
||||||
UntilTime time.Time `json:"until_time"`
|
UntilTime time.Time `json:"until_time"`
|
||||||
|
ValveState string `json:"valve_state"`
|
||||||
|
LocalTemperature int `json:"local_temperature"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *DeviceState) Equivalent(state DeviceState) bool {
|
func (s *DeviceState) Equivalent(state DeviceState) bool {
|
||||||
@ -136,12 +137,15 @@ func (d *Device) SetSetpoint(value int, pubchan chan Message) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (d *Device) SetState(log zerolog.Logger, state DeviceState, pubchan chan Message) error {
|
func (d *Device) SetState(log zerolog.Logger, state DeviceState, pubchan chan Message) error {
|
||||||
|
// Called on mqtt state/set cmd received
|
||||||
// If same state do nothing
|
// If same state do nothing
|
||||||
// else use checksetpoint for changing state
|
|
||||||
if d.State.Equivalent(state) {
|
if d.State.Equivalent(state) {
|
||||||
log.Debug().Msg("same state no change")
|
log.Debug().Msg("same state no change")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
// keep tvr state
|
||||||
|
state.LocalTemperature = d.State.LocalTemperature
|
||||||
|
state.ValveState = d.State.ValveState
|
||||||
|
|
||||||
d.State = state
|
d.State = state
|
||||||
|
|
||||||
@ -213,19 +217,38 @@ func (d *Device) onMessage(ctx context.Context, msg mqtt.Message) {
|
|||||||
log.Error().Err(err).Msg("during payload parse")
|
log.Error().Err(err).Msg("during payload parse")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
// Setpoint
|
||||||
x, err := jp.ParseString(d.Settings.TVR.Setpoint_state_jp)
|
setpoint, err := d.Settings.TVR.ParseSetpoint(obj)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error().Err(err).Msg("while parsing payload")
|
log.Error().Err(err).Msg("while parsing setpoint")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
d.CurrentSetpoint = setpoint
|
||||||
|
|
||||||
r := x.First(obj)
|
// LocalTemperature
|
||||||
|
localTemperature, err := d.Settings.TVR.ParseLocalTemperature(obj)
|
||||||
|
if err != nil {
|
||||||
|
log.Error().Err(err).Msg("while parsing LocalTemperature")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
d.State.LocalTemperature = localTemperature
|
||||||
|
|
||||||
if v, ok := r.(int64); ok {
|
// Valve
|
||||||
d.CurrentSetpoint = int(v)
|
valve, err := d.Settings.TVR.ParseValve(obj)
|
||||||
|
if err != nil {
|
||||||
|
log.Error().Err(err).Msg("while parsing Valve")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
d.State.ValveState = valve
|
||||||
|
|
||||||
|
if v := ctx.Value("pubchan"); v != nil {
|
||||||
|
if pubchan, ok := v.(chan Message); ok {
|
||||||
|
d.publishState(pubchan)
|
||||||
} else {
|
} else {
|
||||||
log.Error().Err(err).Interface("parsing payload", r).Msg("while parsing payload")
|
log.Error().Msg("invalid pubchan ctx type")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log.Error().Msg("pubchan not found in ctx")
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -417,7 +417,7 @@ func TestUpdate(t *testing.T) {
|
|||||||
|
|
||||||
go func(result chan Message, changechan chan bool, errchan chan error) {
|
go func(result chan Message, changechan chan bool, errchan chan error) {
|
||||||
logger := zerolog.New(ioutil.Discard).With().Timestamp().Logger()
|
logger := zerolog.New(ioutil.Discard).With().Timestamp().Logger()
|
||||||
change, err := tt.device.update(&logger, result)
|
change, err := tt.device.update(logger, result)
|
||||||
errchan <- err
|
errchan <- err
|
||||||
changechan <- change
|
changechan <- change
|
||||||
close(rchan)
|
close(rchan)
|
||||||
|
@ -5,6 +5,8 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"text/template"
|
"text/template"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/ohler55/ojg/jp"
|
||||||
)
|
)
|
||||||
|
|
||||||
type DayOfWeek int
|
type DayOfWeek int
|
||||||
@ -153,6 +155,53 @@ type TVRSettings struct {
|
|||||||
Setpoint_payload string `json:"setpoint_payload"`
|
Setpoint_payload string `json:"setpoint_payload"`
|
||||||
Setpoint_state_topic string `json:"setpoint_state_topic"`
|
Setpoint_state_topic string `json:"setpoint_state_topic"`
|
||||||
Setpoint_state_jp string `json:"setpoint_state_jp"`
|
Setpoint_state_jp string `json:"setpoint_state_jp"`
|
||||||
|
StateLocalTemperatureJP string `json:"state_local_temperature_jp"`
|
||||||
|
StateValveJP string `json:"state_valve_jp"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s TVRSettings) ParseSetpoint(obj interface{}) (int, error) {
|
||||||
|
jp, err := jp.ParseString(s.Setpoint_state_jp)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
r := jp.First(obj)
|
||||||
|
|
||||||
|
if v, ok := r.(int64); ok {
|
||||||
|
return int(v), nil
|
||||||
|
} else {
|
||||||
|
return 0, Error("Unexpected type")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s TVRSettings) ParseLocalTemperature(obj interface{}) (int, error) {
|
||||||
|
jp, err := jp.ParseString(s.StateLocalTemperatureJP)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
r := jp.First(obj)
|
||||||
|
|
||||||
|
if v, ok := r.(int64); ok {
|
||||||
|
return int(v), nil
|
||||||
|
} else {
|
||||||
|
return 0, Error("Unexpected type")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s TVRSettings) ParseValve(obj interface{}) (string, error) {
|
||||||
|
jp, err := jp.ParseString(s.StateValveJP)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
r := jp.First(obj)
|
||||||
|
|
||||||
|
if v, ok := r.(string); ok {
|
||||||
|
return string(v), nil
|
||||||
|
} else {
|
||||||
|
return "", Error("Unexpected type")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s TVRSettings) FormatTopicState(device_name string) (string, error) {
|
func (s TVRSettings) FormatTopicState(device_name string) (string, error) {
|
||||||
@ -246,6 +295,8 @@ var DefaultTVRSettings = TVRSettings{
|
|||||||
Setpoint_payload: "{\"current_heating_setpoint\": {{.Setpoint}}}",
|
Setpoint_payload: "{\"current_heating_setpoint\": {{.Setpoint}}}",
|
||||||
Setpoint_state_topic: "zigbee2mqtt/TVR/{{.Device}}",
|
Setpoint_state_topic: "zigbee2mqtt/TVR/{{.Device}}",
|
||||||
Setpoint_state_jp: "$.current_heating_setpoint",
|
Setpoint_state_jp: "$.current_heating_setpoint",
|
||||||
|
StateLocalTemperatureJP: "$.local_temperature",
|
||||||
|
StateValveJP: "$.valve_state",
|
||||||
}
|
}
|
||||||
|
|
||||||
var DefaultDeviceSettings = DeviceSettings{
|
var DefaultDeviceSettings = DeviceSettings{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user