Add myStrom switch (#3832)
This commit is contained in:
parent
bdf9857c47
commit
c013dc53f8
9 changed files with 249 additions and 0 deletions
30
charger/helper.go
Normal file
30
charger/helper.go
Normal 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
78
charger/mystrom.go
Normal 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
27
meter/mystrom.go
Normal 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
46
meter/mystrom/mystrom.go
Normal 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
|
||||
}
|
||||
16
templates/definition/charger/mystrom.yaml
Normal file
16
templates/definition/charger/mystrom.yaml
Normal 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 }}
|
||||
13
templates/definition/meter/mystrom.yaml
Normal file
13
templates/definition/meter/mystrom.yaml
Normal 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 }}
|
||||
19
templates/docs/charger/mystrom_0.yaml
Normal file
19
templates/docs/charger/mystrom_0.yaml
Normal 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
|
||||
17
templates/docs/meter/mystrom_0.yaml
Normal file
17
templates/docs/meter/mystrom_0.yaml
Normal 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
|
||||
|
|
@ -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",
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue