Harmonise switch sockets status and power api implementations (#3833)
This commit is contained in:
parent
ffd5eb03a7
commit
03da7205c2
10 changed files with 140 additions and 373 deletions
|
|
@ -14,8 +14,8 @@ import (
|
|||
|
||||
// FritzDECT charger implementation
|
||||
type FritzDECT struct {
|
||||
conn *fritzdect.Connection
|
||||
standbypower float64
|
||||
conn *fritzdect.Connection
|
||||
*switchSocket
|
||||
}
|
||||
|
||||
func init() {
|
||||
|
|
@ -40,12 +40,31 @@ func NewFritzDECTFromConfig(other map[string]interface{}) (api.Charger, error) {
|
|||
func NewFritzDECT(uri, ain, user, password string, standbypower float64) (*FritzDECT, error) {
|
||||
conn, err := fritzdect.NewConnection(uri, ain, user, password)
|
||||
|
||||
m := &FritzDECT{
|
||||
conn: conn,
|
||||
standbypower: standbypower,
|
||||
c := &FritzDECT{
|
||||
conn: conn,
|
||||
}
|
||||
|
||||
return m, err
|
||||
c.switchSocket = NewSwitchSocket(c.Enabled, c.conn.CurrentPower, standbypower)
|
||||
|
||||
return c, err
|
||||
}
|
||||
|
||||
// Status implements the api.Charger interface
|
||||
func (c *FritzDECT) Status() (api.ChargeStatus, error) {
|
||||
resp, err := c.conn.ExecCmd("getswitchpresent")
|
||||
|
||||
if err == nil {
|
||||
var present bool
|
||||
present, err = strconv.ParseBool(resp)
|
||||
if err == nil && !present {
|
||||
err = api.ErrNotAvailable
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
return api.StatusNone, err
|
||||
}
|
||||
|
||||
return c.switchSocket.Status()
|
||||
}
|
||||
|
||||
// Enabled implements the api.Charger interface
|
||||
|
|
@ -84,64 +103,6 @@ func (c *FritzDECT) MaxCurrent(current int64) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// Status implements the api.Charger interface
|
||||
func (c *FritzDECT) Status() (api.ChargeStatus, error) {
|
||||
resp, err := c.conn.ExecCmd("getswitchpresent")
|
||||
|
||||
if err == nil {
|
||||
var present bool
|
||||
present, err = strconv.ParseBool(resp)
|
||||
if err == nil && !present {
|
||||
err = api.ErrNotAvailable
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
return api.StatusNone, err
|
||||
}
|
||||
|
||||
res := api.StatusB
|
||||
on, err := c.Enabled()
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
|
||||
power, err := c.conn.CurrentPower()
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
|
||||
// static mode || standby power mode condition
|
||||
if on && (c.standbypower < 0 || power > c.standbypower) {
|
||||
res = api.StatusC
|
||||
}
|
||||
|
||||
return res, nil
|
||||
}
|
||||
|
||||
var _ api.Meter = (*FritzDECT)(nil)
|
||||
|
||||
// CurrentPower implements the api.Meter interface
|
||||
func (c *FritzDECT) CurrentPower() (float64, error) {
|
||||
var power float64
|
||||
|
||||
// set fix static power in static mode
|
||||
if c.standbypower < 0 {
|
||||
on, err := c.Enabled()
|
||||
if on {
|
||||
power = -c.standbypower
|
||||
}
|
||||
return power, err
|
||||
}
|
||||
|
||||
// ignore power in standby mode
|
||||
power, err := c.conn.CurrentPower()
|
||||
if power <= c.standbypower {
|
||||
power = 0
|
||||
}
|
||||
|
||||
return power, err
|
||||
}
|
||||
|
||||
var _ api.MeterEnergy = (*FritzDECT)(nil)
|
||||
|
||||
// TotalEnergy implements the api.MeterEnergy interface
|
||||
|
|
|
|||
|
|
@ -1,30 +0,0 @@
|
|||
package charger
|
||||
|
||||
import "github.com/evcc-io/evcc/api"
|
||||
|
||||
// switchStatus calculates a generic switches status
|
||||
func switchStatus(
|
||||
enabled func() (bool, error),
|
||||
currentPower func() (float64, error),
|
||||
standbypower float64,
|
||||
) (api.ChargeStatus, error) {
|
||||
res := api.StatusB
|
||||
|
||||
// static mode
|
||||
if standbypower < 0 {
|
||||
on, err := enabled()
|
||||
if on {
|
||||
res = api.StatusC
|
||||
}
|
||||
|
||||
return res, err
|
||||
}
|
||||
|
||||
// standby power mode
|
||||
power, err := currentPower()
|
||||
if power > standbypower {
|
||||
res = api.StatusC
|
||||
}
|
||||
|
||||
return res, err
|
||||
}
|
||||
|
|
@ -8,8 +8,8 @@ import (
|
|||
|
||||
// Homematic CCU charger implementation
|
||||
type CCU struct {
|
||||
conn *homematic.Connection
|
||||
standbypower float64
|
||||
conn *homematic.Connection
|
||||
*switchSocket
|
||||
}
|
||||
|
||||
func init() {
|
||||
|
|
@ -39,12 +39,13 @@ func NewCCUFromConfig(other map[string]interface{}) (api.Charger, error) {
|
|||
func NewCCU(uri, deviceid, meterid, switchid, user, password string, standbypower float64) (*CCU, error) {
|
||||
conn, err := homematic.NewConnection(uri, deviceid, meterid, switchid, user, password)
|
||||
|
||||
wb := &CCU{
|
||||
conn: conn,
|
||||
standbypower: standbypower,
|
||||
c := &CCU{
|
||||
conn: conn,
|
||||
}
|
||||
|
||||
return wb, err
|
||||
c.switchSocket = NewSwitchSocket(c.Enabled, c.conn.CurrentPower, standbypower)
|
||||
|
||||
return c, err
|
||||
}
|
||||
|
||||
// Enabled implements the api.Charger interface
|
||||
|
|
@ -62,51 +63,6 @@ func (c *CCU) MaxCurrent(current int64) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// Status implements the api.Charger interface
|
||||
func (c *CCU) Status() (api.ChargeStatus, error) {
|
||||
res := api.StatusB
|
||||
on, err := c.Enabled()
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
|
||||
power, err := c.conn.CurrentPower()
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
|
||||
// static mode || standby power mode condition
|
||||
if on && (c.standbypower < 0 || power > c.standbypower) {
|
||||
res = api.StatusC
|
||||
}
|
||||
|
||||
return res, nil
|
||||
}
|
||||
|
||||
var _ api.Meter = (*CCU)(nil)
|
||||
|
||||
// CurrentPower implements the api.Meter interface
|
||||
func (c *CCU) CurrentPower() (float64, error) {
|
||||
var power float64
|
||||
|
||||
// set fix static power in static mode
|
||||
if c.standbypower < 0 {
|
||||
on, err := c.Enabled()
|
||||
if on {
|
||||
power = -c.standbypower
|
||||
}
|
||||
return power, err
|
||||
}
|
||||
|
||||
// ignore power in standby mode
|
||||
power, err := c.conn.CurrentPower()
|
||||
if power <= c.standbypower {
|
||||
power = 0
|
||||
}
|
||||
|
||||
return power, err
|
||||
}
|
||||
|
||||
var _ api.MeterEnergy = (*CCU)(nil)
|
||||
|
||||
// TotalEnergy implements the api.MeterEnergy interface
|
||||
|
|
|
|||
|
|
@ -19,10 +19,10 @@ func init() {
|
|||
|
||||
// MyStrom charger implementation
|
||||
type MyStrom struct {
|
||||
*mystrom.Connection
|
||||
standbypower float64
|
||||
cache time.Duration
|
||||
reportG func() (mystrom.Report, error)
|
||||
conn *mystrom.Connection
|
||||
*switchSocket
|
||||
cache time.Duration
|
||||
reportG func() (mystrom.Report, error)
|
||||
}
|
||||
|
||||
// NewMyStromFromConfig creates a myStrom charger from generic config
|
||||
|
|
@ -40,23 +40,16 @@ func NewMyStromFromConfig(other map[string]interface{}) (api.Charger, error) {
|
|||
}
|
||||
|
||||
c := &MyStrom{
|
||||
Connection: mystrom.NewConnection(cc.URI),
|
||||
standbypower: cc.StandbyPower,
|
||||
cache: cc.Cache,
|
||||
conn: mystrom.NewConnection(cc.URI),
|
||||
cache: cc.Cache,
|
||||
}
|
||||
|
||||
c.reportG = provider.Cached(c.Report, c.cache)
|
||||
c.switchSocket = NewSwitchSocket(c.Enabled, c.conn.CurrentPower, cc.StandbyPower)
|
||||
c.reportG = provider.Cached(c.conn.Report, c.cache)
|
||||
|
||||
return c, nil
|
||||
}
|
||||
|
||||
var _ api.Meter = (*MyStrom)(nil)
|
||||
|
||||
// Status implements the api.Charger interface
|
||||
func (c *MyStrom) Status() (api.ChargeStatus, error) {
|
||||
return switchStatus(c.Enabled, c.CurrentPower, c.standbypower)
|
||||
}
|
||||
|
||||
// Enabled implements the api.Charger interface
|
||||
func (c *MyStrom) Enabled() (bool, error) {
|
||||
res, err := c.reportG()
|
||||
|
|
@ -66,10 +59,10 @@ func (c *MyStrom) Enabled() (bool, error) {
|
|||
// Enable implements the api.Charger interface
|
||||
func (c *MyStrom) Enable(enable bool) error {
|
||||
// reset cache
|
||||
c.reportG = provider.Cached(c.Report, c.cache)
|
||||
c.reportG = provider.Cached(c.conn.Report, c.cache)
|
||||
|
||||
onoff := map[bool]int{false: 0, true: 1}
|
||||
return c.Request(fmt.Sprintf("relay?state=%d", onoff[enable]))
|
||||
return c.conn.Request(fmt.Sprintf("relay?state=%d", onoff[enable]))
|
||||
}
|
||||
|
||||
// MaxCurrent implements the api.Charger interface
|
||||
|
|
|
|||
|
|
@ -10,8 +10,8 @@ import (
|
|||
|
||||
// Shelly charger implementation
|
||||
type Shelly struct {
|
||||
conn *shelly.Connection
|
||||
standbypower float64
|
||||
conn *shelly.Connection
|
||||
*switchSocket
|
||||
}
|
||||
|
||||
func init() {
|
||||
|
|
@ -42,12 +42,13 @@ func NewShelly(uri, user, password string, channel int, standbypower float64) (*
|
|||
return nil, err
|
||||
}
|
||||
|
||||
shelly := &Shelly{
|
||||
conn: conn,
|
||||
standbypower: standbypower,
|
||||
c := &Shelly{
|
||||
conn: conn,
|
||||
}
|
||||
|
||||
return shelly, nil
|
||||
c.switchSocket = NewSwitchSocket(c.Enabled, c.conn.CurrentPower, standbypower)
|
||||
|
||||
return c, nil
|
||||
}
|
||||
|
||||
// Enabled implements the api.Charger interface
|
||||
|
|
@ -78,50 +79,3 @@ func (c *Shelly) Enable(enable bool) error {
|
|||
func (c *Shelly) MaxCurrent(current int64) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Status implements the api.Charger interface
|
||||
func (c *Shelly) Status() (api.ChargeStatus, error) {
|
||||
res := api.StatusB
|
||||
|
||||
// static mode
|
||||
if c.standbypower < 0 {
|
||||
on, err := c.Enabled()
|
||||
if on {
|
||||
res = api.StatusC
|
||||
}
|
||||
|
||||
return res, err
|
||||
}
|
||||
|
||||
// standby power mode
|
||||
power, err := c.CurrentPower()
|
||||
if power > c.standbypower {
|
||||
res = api.StatusC
|
||||
}
|
||||
|
||||
return res, err
|
||||
}
|
||||
|
||||
var _ api.Meter = (*Shelly)(nil)
|
||||
|
||||
// CurrentPower implements the api.Meter interface
|
||||
func (c *Shelly) CurrentPower() (float64, error) {
|
||||
var power float64
|
||||
|
||||
// set fix static power in static mode
|
||||
if c.standbypower < 0 {
|
||||
on, err := c.Enabled()
|
||||
if on {
|
||||
power = -c.standbypower
|
||||
}
|
||||
return power, err
|
||||
}
|
||||
|
||||
// ignore power in standby mode
|
||||
power, err := c.conn.CurrentPower()
|
||||
if power <= c.standbypower {
|
||||
power = 0
|
||||
}
|
||||
|
||||
return power, err
|
||||
}
|
||||
|
|
|
|||
70
charger/switchsocket.go
Normal file
70
charger/switchsocket.go
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
package charger
|
||||
|
||||
import "github.com/evcc-io/evcc/api"
|
||||
|
||||
// switchSocket implements the api.Charger Status and CurrentPower methods
|
||||
// using basic generic switch socket functions
|
||||
type switchSocket struct {
|
||||
enabled func() (bool, error)
|
||||
currentPower func() (float64, error)
|
||||
standbypower float64
|
||||
}
|
||||
|
||||
func NewSwitchSocket(
|
||||
enabled func() (bool, error),
|
||||
currentPower func() (float64, error),
|
||||
standbypower float64,
|
||||
) *switchSocket {
|
||||
return &switchSocket{
|
||||
enabled: enabled,
|
||||
currentPower: currentPower,
|
||||
standbypower: standbypower,
|
||||
}
|
||||
}
|
||||
|
||||
// Status calculates a generic switches status
|
||||
func (c *switchSocket) Status() (api.ChargeStatus, error) {
|
||||
res := api.StatusB
|
||||
|
||||
// static mode
|
||||
if c.standbypower < 0 {
|
||||
on, err := c.enabled()
|
||||
if on {
|
||||
res = api.StatusC
|
||||
}
|
||||
|
||||
return res, err
|
||||
}
|
||||
|
||||
// standby power mode
|
||||
power, err := c.currentPower()
|
||||
if power > c.standbypower {
|
||||
res = api.StatusC
|
||||
}
|
||||
|
||||
return res, err
|
||||
}
|
||||
|
||||
var _ api.Meter = (*switchSocket)(nil)
|
||||
|
||||
// CurrentPower calculates a generic switches power
|
||||
func (c *switchSocket) CurrentPower() (float64, error) {
|
||||
var power float64
|
||||
|
||||
// set fix static power in static mode
|
||||
if c.standbypower < 0 {
|
||||
on, err := c.enabled()
|
||||
if on {
|
||||
power = -c.standbypower
|
||||
}
|
||||
return power, err
|
||||
}
|
||||
|
||||
// ignore power in standby mode
|
||||
power, err := c.currentPower()
|
||||
if power <= c.standbypower {
|
||||
power = 0
|
||||
}
|
||||
|
||||
return power, err
|
||||
}
|
||||
|
|
@ -8,8 +8,8 @@ import (
|
|||
|
||||
// TP-Link Tapo charger implementation
|
||||
type Tapo struct {
|
||||
conn *tapo.Connection
|
||||
standbypower float64
|
||||
conn *tapo.Connection
|
||||
*switchSocket
|
||||
}
|
||||
|
||||
func init() {
|
||||
|
|
@ -39,12 +39,13 @@ func NewTapo(uri, user, password string, standbypower float64) (*Tapo, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
tapo := &Tapo{
|
||||
conn: conn,
|
||||
standbypower: standbypower,
|
||||
c := &Tapo{
|
||||
conn: conn,
|
||||
}
|
||||
|
||||
return tapo, nil
|
||||
c.switchSocket = NewSwitchSocket(c.Enabled, c.conn.CurrentPower, standbypower)
|
||||
|
||||
return c, nil
|
||||
}
|
||||
|
||||
// Enabled implements the api.Charger interface
|
||||
|
|
@ -67,51 +68,6 @@ func (c *Tapo) MaxCurrent(current int64) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// Status implements the api.Charger interface
|
||||
func (c *Tapo) Status() (api.ChargeStatus, error) {
|
||||
res := api.StatusB
|
||||
on, err := c.Enabled()
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
|
||||
power, err := c.conn.CurrentPower()
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
|
||||
// static mode || standby power mode condition
|
||||
if on && (c.standbypower < 0 || power > c.standbypower) {
|
||||
res = api.StatusC
|
||||
}
|
||||
|
||||
return res, nil
|
||||
}
|
||||
|
||||
var _ api.Meter = (*Tapo)(nil)
|
||||
|
||||
// CurrentPower implements the api.Meter interface
|
||||
func (c *Tapo) CurrentPower() (float64, error) {
|
||||
var power float64
|
||||
|
||||
// set fix static power in static mode
|
||||
if c.standbypower < 0 {
|
||||
on, err := c.Enabled()
|
||||
if on {
|
||||
power = -c.standbypower
|
||||
}
|
||||
return power, err
|
||||
}
|
||||
|
||||
// ignore power in standby mode
|
||||
power, err := c.conn.CurrentPower()
|
||||
if power <= c.standbypower {
|
||||
power = 0
|
||||
}
|
||||
|
||||
return power, err
|
||||
}
|
||||
|
||||
var _ api.ChargeRater = (*Tapo)(nil)
|
||||
|
||||
// ChargedEnergy implements the api.ChargeRater interface
|
||||
|
|
|
|||
|
|
@ -17,9 +17,9 @@ import (
|
|||
|
||||
// Tasmota charger implementation
|
||||
type Tasmota struct {
|
||||
conn *tasmota.Connection
|
||||
channel int
|
||||
standbypower float64
|
||||
conn *tasmota.Connection
|
||||
channel int
|
||||
*switchSocket
|
||||
}
|
||||
|
||||
func init() {
|
||||
|
|
@ -53,14 +53,13 @@ func NewTasmota(uri, user, password string, channel int, standbypower float64) (
|
|||
}
|
||||
|
||||
c := &Tasmota{
|
||||
conn: conn,
|
||||
channel: channel,
|
||||
standbypower: standbypower,
|
||||
conn: conn,
|
||||
channel: channel,
|
||||
}
|
||||
|
||||
err = c.channelExists(channel)
|
||||
c.switchSocket = NewSwitchSocket(c.Enabled, c.conn.CurrentPower, standbypower)
|
||||
|
||||
return c, err
|
||||
return c, c.channelExists(channel)
|
||||
}
|
||||
|
||||
// channelExists checks the existence of the configured relay channel interface
|
||||
|
|
@ -173,53 +172,6 @@ func (c *Tasmota) MaxCurrent(current int64) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// Status implements the api.Charger interface
|
||||
func (c *Tasmota) Status() (api.ChargeStatus, error) {
|
||||
res := api.StatusB
|
||||
|
||||
// static mode
|
||||
if c.standbypower < 0 {
|
||||
on, err := c.Enabled()
|
||||
if on {
|
||||
res = api.StatusC
|
||||
}
|
||||
|
||||
return res, err
|
||||
}
|
||||
|
||||
// standby power mode
|
||||
power, err := c.CurrentPower()
|
||||
if power > c.standbypower {
|
||||
res = api.StatusC
|
||||
}
|
||||
|
||||
return res, err
|
||||
}
|
||||
|
||||
var _ api.Meter = (*Tasmota)(nil)
|
||||
|
||||
// CurrentPower implements the api.Meter interface
|
||||
func (c *Tasmota) CurrentPower() (float64, error) {
|
||||
var power float64
|
||||
|
||||
// set fix static power in static mode
|
||||
if c.standbypower < 0 {
|
||||
on, err := c.Enabled()
|
||||
if on {
|
||||
power = -c.standbypower
|
||||
}
|
||||
return power, err
|
||||
}
|
||||
|
||||
// ignore power in standby mode
|
||||
power, err := c.conn.CurrentPower()
|
||||
if power <= c.standbypower {
|
||||
power = 0
|
||||
}
|
||||
|
||||
return power, err
|
||||
}
|
||||
|
||||
var _ api.MeterEnergy = (*Tasmota)(nil)
|
||||
|
||||
// TotalEnergy implements the api.MeterEnergy interface
|
||||
|
|
|
|||
|
|
@ -12,8 +12,8 @@ import (
|
|||
|
||||
// TPLink charger implementation
|
||||
type TPLink struct {
|
||||
conn *tplink.Connection
|
||||
standbypower float64
|
||||
conn *tplink.Connection
|
||||
*switchSocket
|
||||
}
|
||||
|
||||
func init() {
|
||||
|
|
@ -46,9 +46,11 @@ func NewTPLink(uri string, standbypower float64) (*TPLink, error) {
|
|||
}
|
||||
|
||||
c := &TPLink{
|
||||
conn: conn,
|
||||
standbypower: standbypower,
|
||||
conn: conn,
|
||||
}
|
||||
|
||||
c.switchSocket = NewSwitchSocket(c.Enabled, c.conn.CurrentPower, standbypower)
|
||||
|
||||
return c, nil
|
||||
}
|
||||
|
||||
|
|
@ -94,53 +96,6 @@ func (c *TPLink) MaxCurrent(current int64) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// Status implements the api.Charger interface
|
||||
func (c *TPLink) Status() (api.ChargeStatus, error) {
|
||||
res := api.StatusB
|
||||
|
||||
// static mode
|
||||
if c.standbypower < 0 {
|
||||
on, err := c.Enabled()
|
||||
if on {
|
||||
res = api.StatusC
|
||||
}
|
||||
|
||||
return res, err
|
||||
}
|
||||
|
||||
// standby power mode
|
||||
power, err := c.CurrentPower()
|
||||
if power > c.standbypower {
|
||||
res = api.StatusC
|
||||
}
|
||||
|
||||
return res, err
|
||||
}
|
||||
|
||||
var _ api.Meter = (*TPLink)(nil)
|
||||
|
||||
// CurrentPower implements the api.Meter interface
|
||||
func (c *TPLink) CurrentPower() (float64, error) {
|
||||
var power float64
|
||||
|
||||
// set fix static power in static mode
|
||||
if c.standbypower < 0 {
|
||||
on, err := c.Enabled()
|
||||
if on {
|
||||
power = -c.standbypower
|
||||
}
|
||||
return power, err
|
||||
}
|
||||
|
||||
// ignore power in standby mode
|
||||
power, err := c.conn.CurrentPower()
|
||||
if power <= c.standbypower {
|
||||
power = 0
|
||||
}
|
||||
|
||||
return power, err
|
||||
}
|
||||
|
||||
var _ api.MeterEnergy = (*TPLink)(nil)
|
||||
|
||||
// TotalEnergy implements the api.MeterEnergy interface
|
||||
|
|
|
|||
|
|
@ -201,7 +201,7 @@ func (lp *LoadPoint) GetMaxCurrent() float64 {
|
|||
return lp.MaxCurrent
|
||||
}
|
||||
|
||||
// SetMaxCurrent returns the max loadpoint current
|
||||
// SetMaxCurrent sets the max loadpoint current
|
||||
func (lp *LoadPoint) SetMaxCurrent(current float64) {
|
||||
lp.Lock()
|
||||
defer lp.Unlock()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue