From f5fcd77f46ffdc1bb578c6bc8447b1e5b5b2c413 Mon Sep 17 00:00:00 2001 From: Markus Thierolf <77847348+thierolm@users.noreply.github.com> Date: Thu, 7 Jul 2022 13:18:14 +0200 Subject: [PATCH] Tasmota: use SML for grid meter (#3787) --- meter/tasmota.go | 44 ++++++++++++++++++++++++- meter/tasmota/connection.go | 22 +++++++++++++ meter/tasmota/types.go | 5 +++ templates/definition/meter/tasmota.yaml | 1 + 4 files changed, 71 insertions(+), 1 deletion(-) diff --git a/meter/tasmota.go b/meter/tasmota.go index 9c7d65d2a..a0ae9842f 100644 --- a/meter/tasmota.go +++ b/meter/tasmota.go @@ -6,6 +6,12 @@ import ( "github.com/evcc-io/evcc/util" ) +// Tasmota meter implementation +type Tasmota struct { + conn *tasmota.Connection + usage string +} + // Tasmota meter implementation func init() { registry.Add("tasmota", NewTasmotaFromConfig) @@ -17,11 +23,47 @@ func NewTasmotaFromConfig(other map[string]interface{}) (api.Meter, error) { URI string User string Password string + Usage string }{} if err := util.DecodeOther(other, &cc); err != nil { return nil, err } - return tasmota.NewConnection(cc.URI, cc.User, cc.Password) + return NewTasmota(cc.URI, cc.User, cc.Password, cc.Usage) +} + +// NewTasmota creates Tasmota meter +func NewTasmota(uri, user, password, usage string) (*Tasmota, error) { + conn, err := tasmota.NewConnection(uri, user, password) + if err != nil { + return nil, err + } + + c := &Tasmota{ + conn: conn, + usage: usage, + } + + return c, err +} + +var _ api.Meter = (*Tasmota)(nil) + +// CurrentPower implements the api.Meter interface +func (c *Tasmota) CurrentPower() (float64, error) { + if c.usage == "grid" { + return c.conn.GridCurrentPower() + } + return c.conn.CurrentPower() +} + +var _ api.MeterEnergy = (*Tasmota)(nil) + +// TotalEnergy implements the api.MeterEnergy interface +func (c *Tasmota) TotalEnergy() (float64, error) { + if c.usage == "grid" { + return c.conn.GridTotalEnergy() + } + return c.conn.TotalEnergy() } diff --git a/meter/tasmota/connection.go b/meter/tasmota/connection.go index 9254caa0f..903bbb586 100644 --- a/meter/tasmota/connection.go +++ b/meter/tasmota/connection.go @@ -73,3 +73,25 @@ func (d *Connection) TotalEnergy() (float64, error) { return float64(res.StatusSNS.Energy.Total), nil } + +// GridCurrentPower provides current power consumption +func (d *Connection) GridCurrentPower() (float64, error) { + var res *StatusSNSResponse + err := d.ExecCmd("Status 8", &res) + if err != nil { + return 0, err + } + + return float64(res.StatusSNS.SML.Power_curr), nil +} + +// GridTotalEnergy implements the api.MeterEnergy interface +func (d *Connection) GridTotalEnergy() (float64, error) { + var res *StatusSNSResponse + err := d.ExecCmd("Status 8", &res) + if err != nil { + return 0, err + } + + return float64(res.StatusSNS.SML.Total_in), nil +} diff --git a/meter/tasmota/types.go b/meter/tasmota/types.go index a742a0237..13cc5fadd 100644 --- a/meter/tasmota/types.go +++ b/meter/tasmota/types.go @@ -73,5 +73,10 @@ type StatusSNSResponse struct { Voltage int Current float64 } + SML struct { + Total_in float64 + Total_out float64 + Power_curr int + } } } diff --git a/templates/definition/meter/tasmota.yaml b/templates/definition/meter/tasmota.yaml index e97ab5337..cb66c0f8a 100644 --- a/templates/definition/meter/tasmota.yaml +++ b/templates/definition/meter/tasmota.yaml @@ -19,5 +19,6 @@ params: render: | type: tasmota uri: http://{{ .host }} + usage: {{ .usage }} user: {{ .user }} password: {{ .password }}