Tasmota: fix meter config (#3459)
Some checks failed
Release / call-build-workflow (push) Has been cancelled
Release / Publish Docker :release (push) Has been cancelled
Release / Publish Github & APT release (push) Has been cancelled

This commit is contained in:
Markus Thierolf 2022-05-22 12:18:28 +02:00 • committed by GitHub
parent 820047dd4b
commit b814afb624
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 71 additions and 74 deletions

View file

@ -18,6 +18,7 @@ import (
// Tasmota charger implementation
type Tasmota struct {
conn *tasmota.Connection
channel int
standbypower float64
}
@ -36,6 +37,7 @@ func NewTasmotaFromConfig(other map[string]interface{}) (api.Charger, error) {
}{
Channel: 1,
}
if err := util.DecodeOther(other, &cc); err != nil {
return nil, err
}
@ -45,17 +47,54 @@ func NewTasmotaFromConfig(other map[string]interface{}) (api.Charger, error) {
// NewTasmota creates Tasmota charger
func NewTasmota(uri, user, password string, channel int, standbypower float64) (*Tasmota, error) {
conn, err := tasmota.NewConnection(uri, user, password, channel)
conn, err := tasmota.NewConnection(uri, user, password)
if err != nil {
return nil, err
}
c := &Tasmota{
conn: conn,
channel: channel,
standbypower: standbypower,
}
return c, nil
err = c.channelExists(channel)
return c, err
}
// channelExists checks the existence of the configured relay channel interface
func (c *Tasmota) channelExists(channel int) error {
var res *tasmota.StatusSTSResponse
if err := c.conn.ExecCmd("Status 0", &res); err != nil {
return err
}
var ok bool
switch channel {
case 1:
ok = res.StatusSTS.Power != "" || res.StatusSTS.Power1 != ""
case 2:
ok = res.StatusSTS.Power2 != ""
case 3:
ok = res.StatusSTS.Power3 != ""
case 4:
ok = res.StatusSTS.Power4 != ""
case 5:
ok = res.StatusSTS.Power5 != ""
case 6:
ok = res.StatusSTS.Power6 != ""
case 7:
ok = res.StatusSTS.Power7 != ""
case 8:
ok = res.StatusSTS.Power8 != ""
}
if !ok {
return fmt.Errorf("invalid relay channel: %d", channel)
}
return nil
}
// Enabled implements the api.Charger interface
@ -66,7 +105,7 @@ func (c *Tasmota) Enabled() (bool, error) {
return false, err
}
switch c.conn.Channel {
switch c.channel {
case 2:
return strings.ToUpper(res.StatusSTS.Power2) == "ON", err
case 3:
@ -89,18 +128,18 @@ func (c *Tasmota) Enabled() (bool, error) {
// Enable implements the api.Charger interface
func (c *Tasmota) Enable(enable bool) error {
var res tasmota.PowerResponse
on := false
cmd := fmt.Sprintf("Power%d off", c.conn.Channel)
cmd := fmt.Sprintf("Power%d off", c.channel)
if enable {
cmd = fmt.Sprintf("Power%d on", c.conn.Channel)
cmd = fmt.Sprintf("Power%d on", c.channel)
}
err := c.conn.ExecCmd(cmd, &res)
if err != nil {
if err := c.conn.ExecCmd(cmd, &res); err != nil {
return err
}
switch c.conn.Channel {
var on bool
switch c.channel {
case 2:
on = strings.ToUpper(res.Power2) == "ON"
case 3:

View file

@ -11,20 +11,17 @@ func init() {
registry.Add("tasmota", NewTasmotaFromConfig)
}
// NewTapoFromConfig creates a tapo meter from generic config
// NewTasmotaFromConfig creates a Tasmota meter from generic config
func NewTasmotaFromConfig(other map[string]interface{}) (api.Meter, error) {
cc := struct {
URI string
User string
Password string
Channel int
}{
Channel: 1,
}
}{}
if err := util.DecodeOther(other, &cc); err != nil {
return nil, err
}
return tasmota.NewConnection(cc.URI, cc.User, cc.Password, cc.Channel)
return tasmota.NewConnection(cc.URI, cc.User, cc.Password)
}

View file

@ -15,11 +15,10 @@ import (
type Connection struct {
*request.Helper
uri, user, password string
Channel int
}
// NewConnection creates Tasmota charger
func NewConnection(uri, user, password string, channel int) (*Connection, error) {
// NewConnection creates a Tasmota connection
func NewConnection(uri, user, password string) (*Connection, error) {
if uri == "" {
return nil, errors.New("missing uri")
}
@ -30,20 +29,14 @@ func NewConnection(uri, user, password string, channel int) (*Connection, error)
uri: util.DefaultScheme(strings.TrimRight(uri, "/"), "http"),
user: user,
password: password,
Channel: channel,
}
c.Client.Transport = request.NewTripper(log, transport.Insecure())
err := c.ChannelExists()
if err != nil {
return nil, err
}
return c, nil
}
// ExecCmd executes a Tasmota api command and provides the response
// ExecCmd executes an api command and provides the response
func (d *Connection) ExecCmd(cmd string, res interface{}) error {
parameters := url.Values{
"user": []string{d.user},
@ -80,40 +73,3 @@ func (d *Connection) TotalEnergy() (float64, error) {
return float64(res.StatusSNS.Energy.Total), nil
}
// ChannelExists checks the existence of the configured relay channel interface
func (d *Connection) ChannelExists() error {
var res *StatusSTSResponse
err := d.ExecCmd("Status 0", &res)
if err != nil {
return err
}
channelexists := false
switch d.Channel {
case 1:
channelexists = res.StatusSTS.Power != "" || res.StatusSTS.Power1 != ""
case 2:
channelexists = res.StatusSTS.Power2 != ""
case 3:
channelexists = res.StatusSTS.Power3 != ""
case 4:
channelexists = res.StatusSTS.Power4 != ""
case 5:
channelexists = res.StatusSTS.Power5 != ""
case 6:
channelexists = res.StatusSTS.Power6 != ""
case 7:
channelexists = res.StatusSTS.Power7 != ""
case 8:
channelexists = res.StatusSTS.Power8 != ""
default:
channelexists = false
}
if !channelexists {
return errors.New("configured relay channel doesn't exist on device")
}
return nil
}

View file

@ -5,7 +5,7 @@ products:
group: switchsockets
params:
- name: usage
choice: ["pv"]
choice: ["grid", "pv", "battery"]
- name: host
- name: user
required: false
@ -15,18 +15,8 @@ params:
- name: password
required: false
mask: true
- name: channel
default: 1
required: true
description:
de: Nummer des Schalt-Kanals
en: Device relay channel number
help:
de: Nummer des Schalt-Kanals (1-8), bei Geräten mit mehr als einem Schalter
en: Device relay channel number (allowed range 1-8)
render: |
type: tasmota
uri: http://{{ .host }}
user: {{ .user }}
password: {{ .password }}
channel: {{ .channel }} # # relay channel (allowed range: 1-8)

View file

@ -2,6 +2,14 @@ product:
description: Tasmota
group: Schaltbare Steckdosen
render:
- usage: grid
default: |
type: template
template: tasmota
usage: grid
host: 192.0.2.2 # IP-Adresse oder Hostname
user: # Standard-User ist admin # Optional
password: # Passwort des Benutzerkontos (bei führenden Nullen bitte in einfache Hochkommata setzen) # Optional
- usage: pv
default: |
type: template
@ -10,4 +18,11 @@ render:
host: 192.0.2.2 # IP-Adresse oder Hostname
user: # Standard-User ist admin # Optional
password: # Passwort des Benutzerkontos (bei führenden Nullen bitte in einfache Hochkommata setzen) # Optional
channel: 1 # Nummer des Schalt-Kanals (1-8), bei Geräten mit mehr als einem Schalter
- usage: battery
default: |
type: template
template: tasmota
usage: battery
host: 192.0.2.2 # IP-Adresse oder Hostname
user: # Standard-User ist admin # Optional
password: # Passwort des Benutzerkontos (bei führenden Nullen bitte in einfache Hochkommata setzen) # Optional