Add support for my-PV AC ELWA-E (#23358)

This commit is contained in:
Jannis M. 2025-09-06 00:11:09 +02:00 • committed by GitHub
parent e48f3c4007
commit dda8b56029
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 53 additions and 14 deletions

View file

@ -21,6 +21,7 @@ import (
"context"
"encoding/binary"
"fmt"
"slices"
"sync/atomic"
"time"
@ -45,12 +46,13 @@ type MyPv struct {
}
const (
elwaRegSetPower = 1000
elwaRegTempLimit = 1002
elwaRegStatus = 1003
elwaRegLoadState = 1059
elwaRegPower = 1000 // https://github.com/evcc-io/evcc/issues/18020#issuecomment-2585300804
elwaRegOperationState = 1077
elwaRegSetPower = 1000
elwaRegTempLimit = 1002
elwaRegStatus = 1003
elwaRegLoadState = 1059
elwaRegPower = 1000 // https://github.com/evcc-io/evcc/issues/18020#issuecomment-2585300804
elwaRegOperationState = 1077
elwaERegOperationState = elwaRegStatus // same register for elwa-e operation state
)
var elwaTemp = []uint16{1001, 1030, 1031}
@ -66,6 +68,10 @@ func init() {
registry.AddCtx("ac-thor", func(ctx context.Context, other map[string]interface{}) (api.Charger, error) {
return newMyPvFromConfig(ctx, "ac-thor", other, 9)
})
registry.AddCtx("ac-elwa-e", func(ctx context.Context, other map[string]interface{}) (api.Charger, error) {
return newMyPvFromConfig(ctx, "ac-elwa-e", other, 2)
})
}
// newMyPvFromConfig creates a MyPv charger from generic config
@ -194,20 +200,29 @@ func (wb *MyPv) Status() (api.ChargeStatus, error) {
// Enabled implements the api.Charger interface
func (wb *MyPv) Enabled() (bool, error) {
b, err := wb.conn.ReadHoldingRegisters(elwaRegOperationState, 1)
// "ac-thor" and "ac-elwa-2"
reg := elwaRegOperationState
enabled := []uint16{1, 2} // heating PV excess, boost backup
if wb.name == "ac-elwa-e" {
reg = elwaERegOperationState
enabled = []uint16{2, 4} // heating PV excess, boost backup
}
// register read
b, err := wb.conn.ReadHoldingRegisters(uint16(reg), 1)
if err != nil {
return false, err
}
state := binary.BigEndian.Uint16(b)
switch binary.BigEndian.Uint16(b) {
case
1, // heating PV excess
2: // boost backup
return true, nil
case
0: // standby
// determine enabled state
if state == 0 { // standby
return false, nil
}
if slices.Contains(enabled, state) {
return true, nil
}
// fallback to cached value as last resort
return wb.enabled, nil

View file

@ -0,0 +1,24 @@
template: ac-elwa-e
products:
- brand: my-PV
description:
generic: AC ELWA-E
group: heating
requirements:
description:
de: Für den Heizstab von my-PV ohne Display. Über das lokale Webinterface des AC ELWA-E muss der Wert für die "Zeitablauf Ansteuerung" auf einen Wert etwas größer der Intervall Zeit von evcc (z.B. + 5s) gesetzt werden.
en: For the heating rod from my-PV without a display. Use the local web interface of AC ELWA-E to set the value "Power timeout" to a value slightly higher (e.g. + 5s) than the interval time of evcc.
evcc: ["sponsorship"]
params:
- name: modbus
choice: ["tcpip"]
- name: scale
type: float
default: 1
description:
en: "Scale factor for power limit"
de: "Skalierungsfaktor der Leistungsvorgabe"
render: |
type: ac-elwa-e
{{- include "modbus" . }}
scale: {{ .scale }}