Add myStrom switch (#3832)

This commit is contained in:
andig 2022-07-13 18:17:54 +02:00 • committed by GitHub
parent bdf9857c47
commit c013dc53f8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 249 additions and 0 deletions

30
charger/helper.go Normal file
View file

@ -0,0 +1,30 @@
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
}

78
charger/mystrom.go Normal file
View file

@ -0,0 +1,78 @@
package charger
import (
"fmt"
"time"
"github.com/evcc-io/evcc/api"
"github.com/evcc-io/evcc/meter/mystrom"
"github.com/evcc-io/evcc/provider"
"github.com/evcc-io/evcc/util"
)
// myStrom switch:
// https://api.mystrom.ch/#fbb2c698-e37a-4584-9324-3f8b2f615fe2
func init() {
registry.Add("mystrom", NewMyStromFromConfig)
}
// MyStrom charger implementation
type MyStrom struct {
*mystrom.Connection
standbypower float64
cache time.Duration
reportG func() (mystrom.Report, error)
}
// NewMyStromFromConfig creates a myStrom charger from generic config
func NewMyStromFromConfig(other map[string]interface{}) (api.Charger, error) {
cc := struct {
URI string
StandbyPower float64
Cache time.Duration
}{
Cache: time.Second,
}
if err := util.DecodeOther(other, &cc); err != nil {
return nil, err
}
c := &MyStrom{
Connection: mystrom.NewConnection(cc.URI),
standbypower: cc.StandbyPower,
cache: cc.Cache,
}
c.reportG = provider.Cached(c.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()
return res.Relay, err
}
// Enable implements the api.Charger interface
func (c *MyStrom) Enable(enable bool) error {
// reset cache
c.reportG = provider.Cached(c.Report, c.cache)
onoff := map[bool]int{false: 0, true: 1}
return c.Request(fmt.Sprintf("relay/state=%d", onoff[enable]))
}
// MaxCurrent implements the api.Charger interface
func (c *MyStrom) MaxCurrent(current int64) error {
return nil
}

27
meter/mystrom.go Normal file
View file

@ -0,0 +1,27 @@
package meter
import (
"github.com/evcc-io/evcc/api"
"github.com/evcc-io/evcc/meter/mystrom"
"github.com/evcc-io/evcc/util"
)
// myStrom switch:
// https://api.mystrom.ch/#fbb2c698-e37a-4584-9324-3f8b2f615fe2
func init() {
registry.Add("mystrom", NewMyStromFromConfig)
}
// NewMyStromFromConfig creates a myStrom meter from generic config
func NewMyStromFromConfig(other map[string]interface{}) (api.Meter, error) {
var cc struct {
URI string
}
if err := util.DecodeOther(other, &cc); err != nil {
return nil, err
}
return mystrom.NewConnection(cc.URI), nil
}

46
meter/mystrom/mystrom.go Normal file
View file

@ -0,0 +1,46 @@
package mystrom
import (
"fmt"
"github.com/evcc-io/evcc/api"
"github.com/evcc-io/evcc/util"
"github.com/evcc-io/evcc/util/request"
)
type Report struct {
Power float64
Relay bool
}
type Connection struct {
*request.Helper
uri string
}
func NewConnection(uri string) *Connection {
return &Connection{
uri: uri,
Helper: request.NewHelper(util.NewLogger("mystrom")),
}
}
func (c *Connection) Request(path string) error {
uri := fmt.Sprintf("%s/%s", c.uri, path)
return c.GetJSON(uri, nil)
}
func (c *Connection) Report() (Report, error) {
var res Report
uri := fmt.Sprintf("%s/report", c.uri)
err := c.GetJSON(uri, &res)
return res, err
}
var _ api.Meter = (*Connection)(nil)
// CurrentPower implements the api.Meter interface
func (c *Connection) CurrentPower() (float64, error) {
res, err := c.Report()
return res.Power, err
}

View file

@ -0,0 +1,16 @@
template: mystrom
products:
- brand: myStrom
description:
generic: Switch
group: switchsockets
params:
- name: usage
choice: ["pv", "charge"]
- name: host
- name: standbypower
default: 15
render: |
type: mystrom
uri: http://{{ .host }}
standbypower: {{ .standbypower }}

View file

@ -0,0 +1,13 @@
template: mystrom
products:
- brand: myStrom
description:
generic: Switch
group: switchsockets
params:
- name: usage
choice: ["pv", "charge"]
- name: host
render: |
type: mystrom
uri: http://{{ .host }}

View file

@ -0,0 +1,19 @@
product:
brand: myStrom
description: Switch
group: Schaltbare Steckdosen
render:
- usage: pv
default: |
type: template
template: mystrom
usage: pv
host: 192.0.2.2 # IP-Adresse oder Hostname
standbypower: 15 # Leistung oberhalb des angegebenen Wertes wird als Ladeleistung gewertet # Optional
- usage: charge
default: |
type: template
template: mystrom
usage: charge
host: 192.0.2.2 # IP-Adresse oder Hostname
standbypower: 15 # Leistung oberhalb des angegebenen Wertes wird als Ladeleistung gewertet # Optional

View file

@ -0,0 +1,17 @@
product:
brand: myStrom
description: Switch
group: Schaltbare Steckdosen
render:
- usage: pv
default: |
type: template
template: mystrom
usage: pv
host: 192.0.2.2 # IP-Adresse oder Hostname
- usage: charge
default: |
type: template
template: mystrom
usage: charge
host: 192.0.2.2 # IP-Adresse oder Hostname

View file

@ -44,6 +44,7 @@
"SmartPlugs": [
"AVM",
"Homematic IP",
"myStrom",
"Shelly",
"Tasmota",
"TP-Link"
@ -62,6 +63,7 @@
"Janitza",
"Kostal",
"LG",
"myStrom",
"OpenEMS",
"Powerfox",
"RCT",
@ -92,6 +94,7 @@
"Janitza",
"Kostal",
"LG",
"myStrom",
"OpenEMS",
"RCT",
"SENEC",