Tinkerforge: fix meter api and phase switching (BC) (#27334)
This commit is contained in:
parent
0c1dcfc69a
commit
276316ed9b
4 changed files with 48 additions and 37 deletions
|
|
@ -27,10 +27,10 @@ type WarpWS struct {
|
|||
*request.Helper
|
||||
|
||||
// config
|
||||
emHelper *request.Helper
|
||||
pmHelper *request.Helper
|
||||
log *util.Logger
|
||||
uri string
|
||||
emURI string
|
||||
pmURI string
|
||||
meterIndex uint
|
||||
|
||||
mu sync.RWMutex
|
||||
|
|
@ -97,26 +97,27 @@ func NewWarpWSFromConfig(ctx context.Context, other map[string]any) (api.Charger
|
|||
totalEnergy = wb.totalEnergy
|
||||
}
|
||||
|
||||
// Feature: Phases
|
||||
// Feature: Meters | MeterAllValues
|
||||
var currents, voltages func() (float64, float64, float64, error)
|
||||
if wb.hasFeature(warp.FeatureMeters) || wb.hasFeature(warp.FeatureMeterAllValues) {
|
||||
currents = wb.currents
|
||||
voltages = wb.voltages
|
||||
}
|
||||
|
||||
if wb.hasFeature(warp.FeaturePhaseSwitch) && wb.emURI == "" {
|
||||
wb.emURI = wb.uri
|
||||
wb.emHelper = wb.Helper
|
||||
// Feature: Phase Switching
|
||||
if wb.hasFeature(warp.FeaturePhaseSwitch) && wb.pmURI == "" {
|
||||
wb.pmURI = wb.uri
|
||||
wb.pmHelper = wb.Helper
|
||||
} else if cc.EnergyManagerURI != "" { // fallback to Energy Manager
|
||||
wb.emURI, err = parseURI(cc.EnergyManagerURI, false)
|
||||
if wb.emURI == "" {
|
||||
wb.pmURI, err = parseURI(cc.EnergyManagerURI, false)
|
||||
if wb.pmURI == "" {
|
||||
return nil, err
|
||||
} else if err != nil {
|
||||
wb.log.DEBUG.Println(err)
|
||||
}
|
||||
wb.emHelper = request.NewHelper(wb.log)
|
||||
wb.pmHelper = request.NewHelper(wb.log)
|
||||
if cc.EnergyManagerUser != "" {
|
||||
wb.emHelper.Client.Transport = digest.NewTransport(cc.EnergyManagerUser, cc.EnergyManagerPassword, wb.emHelper.Client.Transport)
|
||||
wb.pmHelper.Client.Transport = digest.NewTransport(cc.EnergyManagerUser, cc.EnergyManagerPassword, wb.pmHelper.Client.Transport)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -126,12 +127,15 @@ func NewWarpWSFromConfig(ctx context.Context, other map[string]any) (api.Charger
|
|||
identify = wb.identify
|
||||
}
|
||||
|
||||
// Feature: EM
|
||||
// only setup phase switching methods if power manager endpoint is set
|
||||
var phases func(int) error
|
||||
var getPhases func() (int, error)
|
||||
if wb.pmState.ExternalControl != 1 {
|
||||
phases = wb.phases1p3p
|
||||
getPhases = wb.getPhases
|
||||
if wb.pmURI != "" {
|
||||
if res, err := wb.ensurePmState(); err == nil && res.ExternalControl != warp.ExternalControlDeactivated {
|
||||
wb.pmState = res
|
||||
phases = wb.phases1p3p
|
||||
getPhases = wb.getPhases
|
||||
}
|
||||
}
|
||||
|
||||
// Phase Auto Switching needs to be disabled for WARP3
|
||||
|
|
@ -234,6 +238,7 @@ func (w *WarpWS) handleConnection(ctx context.Context, conn *websocket.Conn) err
|
|||
return err
|
||||
}
|
||||
|
||||
w.log.TRACE.Printf("ws event %s: %s", event.Topic, event.Payload)
|
||||
if err := w.handleEvent(event.Topic, event.Payload); err != nil {
|
||||
w.log.ERROR.Printf("bad payload for topic %s: %v", event.Topic, err)
|
||||
}
|
||||
|
|
@ -258,7 +263,7 @@ func (w *WarpWS) handleEvent(topic string, payload json.RawMessage) error {
|
|||
case "evse/state":
|
||||
err = json.Unmarshal(payload, &w.evse.State)
|
||||
case "meter/all_values":
|
||||
if !slices.Contains(w.features, warp.FeatureMeters) {
|
||||
if !slices.Contains(w.features, warp.FeatureMeterAllValues) || slices.Contains(w.features, warp.FeatureMeters) {
|
||||
return nil
|
||||
}
|
||||
err = json.Unmarshal(payload, &w.meter.TmpValues)
|
||||
|
|
@ -267,7 +272,7 @@ func (w *WarpWS) handleEvent(topic string, payload json.RawMessage) error {
|
|||
copy(w.meter.Currents[:], w.meter.TmpValues[3:6])
|
||||
}
|
||||
case "meter/values":
|
||||
if !slices.Contains(w.features, warp.FeatureMeters) {
|
||||
if !slices.Contains(w.features, warp.FeatureMeter) || slices.Contains(w.features, warp.FeatureMeters) {
|
||||
return nil
|
||||
}
|
||||
err = json.Unmarshal(payload, &w.meter)
|
||||
|
|
@ -442,8 +447,8 @@ func (w *WarpWS) phases1p3p(phases int) error {
|
|||
return fmt.Errorf("external control not available: %d", ec.ExternalControl)
|
||||
}
|
||||
w.mu.RLock()
|
||||
em := w.emHelper
|
||||
uri := fmt.Sprintf("%s/power_manager/external_control", w.emURI)
|
||||
em := w.pmHelper
|
||||
uri := fmt.Sprintf("%s/power_manager/external_control", w.pmURI)
|
||||
w.mu.RUnlock()
|
||||
|
||||
req, _ := request.New(http.MethodPost, uri, request.MarshalJSON(map[string]int{"phases_wanted": phases}), request.JSONEncoding)
|
||||
|
|
@ -473,8 +478,8 @@ func (w *WarpWS) getPhases() (int, error) {
|
|||
func (w *WarpWS) ensurePmLowLevelState() (warp.PmLowLevelState, error) {
|
||||
w.mu.RLock()
|
||||
s := w.pmLowLevelState
|
||||
em := w.emHelper
|
||||
uri := w.emURI
|
||||
em := w.pmHelper
|
||||
uri := w.pmURI
|
||||
w.mu.RUnlock()
|
||||
if em == nil || uri == "" {
|
||||
return s, nil
|
||||
|
|
@ -495,11 +500,11 @@ func (w *WarpWS) ensurePmLowLevelState() (warp.PmLowLevelState, error) {
|
|||
func (w *WarpWS) ensurePmState() (warp.PmState, error) {
|
||||
w.mu.RLock()
|
||||
s := w.pmState
|
||||
em := w.emHelper
|
||||
uri := w.emURI
|
||||
em := w.pmHelper
|
||||
uri := w.pmURI
|
||||
w.mu.RUnlock()
|
||||
|
||||
if em == nil || uri == "" || s.ExternalControl != 0 {
|
||||
if em == nil || uri == "" || s.ExternalControl != warp.ExternalControlAvailable {
|
||||
return s, nil
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,14 +1,12 @@
|
|||
template: tinkerforge-warp3-ws
|
||||
template: tinkerforge-warp-ws
|
||||
products:
|
||||
- { brand: TinkerForge, description: { generic: WARP2 Smart } }
|
||||
- { brand: TinkerForge, description: { generic: WARP2 Pro } }
|
||||
- { brand: TinkerForge, description: { generic: WARP3 Smart } }
|
||||
- { brand: TinkerForge, description: { generic: WARP3 Pro } }
|
||||
capabilities: ["mA", "1p3p", "rfid"]
|
||||
requirements:
|
||||
description:
|
||||
de: Die automatische Phasenumschaltung bei 1p Fahrzeugen muss deaktiviert sein. Siehe [docs.warp-charger.com](https://docs.warp-charger.com/docs/mqtt_http/api_reference/evse#evse_phase_auto_switch_warp3).
|
||||
en: The automatic phase switching for 1p vehicles must be deactivated. See [docs.warp-charger.com](https://docs.warp-charger.com/docs/mqtt_http/api_reference/evse#evse_phase_auto_switch_warp3).
|
||||
de: Die WARP-eigene automatische Phasenumschaltung wird von EVCC beim Verbinden mit der Wallbox deaktiviert. Siehe [docs.warp-charger.com](https://docs.warp-charger.com/docs/mqtt_http/api_reference/evse#evse_phase_auto_switch_warp3).
|
||||
en: WARP's own automatic phase switching will be deactivated by EVCC when connecting to the wallbox. See [docs.warp-charger.com](https://docs.warp-charger.com/docs/mqtt_http/api_reference/evse#evse_phase_auto_switch_warp3).
|
||||
evcc: ["skiptest"]
|
||||
params:
|
||||
- name: uri
|
||||
|
|
@ -28,5 +26,5 @@ render: |
|
|||
uri: {{ .uri }}
|
||||
user: {{ .user }}
|
||||
password: {{ .password }}
|
||||
energyMeterIndex: {{ .energyMeterIndex }}
|
||||
energyMeterIndex: {{ .energyMeterIndex }}
|
||||
disablePhaseAutoSwitch: true
|
||||
|
|
|
|||
|
|
@ -1,12 +1,11 @@
|
|||
template: tinkerforge-warp-ws
|
||||
template: tinkerforge-warp1-ws
|
||||
products:
|
||||
- { brand: TinkerForge, description: { generic: WARP2 Smart } }
|
||||
- { brand: TinkerForge, description: { generic: WARP2 Pro } }
|
||||
- { brand: TinkerForge, description: { generic: WARP1 Smart } }
|
||||
- { brand: TinkerForge, description: { generic: WARP1 Pro } }
|
||||
capabilities: ["mA", "1p3p", "rfid"]
|
||||
capabilities: ["mA", "rfid"]
|
||||
requirements:
|
||||
description:
|
||||
de: Die automatische Phasenumschaltung bei 1p Fahrzeugen muss deaktiviert sein. Siehe [docs.warp-charger.com](https://docs.warp-charger.com/docs/mqtt_http/api_reference/evse#evse_phase_auto_switch_warp3).
|
||||
en: The automatic phase switching for 1p vehicles must be deactivated. See [docs.warp-charger.com](https://docs.warp-charger.com/docs/mqtt_http/api_reference/evse#evse_phase_auto_switch_warp3).
|
||||
evcc: ["skiptest"]
|
||||
params:
|
||||
- name: uri
|
||||
|
|
|
|||
|
|
@ -1,18 +1,26 @@
|
|||
template: tinkerforge-warp2-ws
|
||||
template: tinkerforge-warp2-em-ws
|
||||
products:
|
||||
- { brand: TinkerForge, description: { generic: WARP2 Smart + Energy Manager } }
|
||||
- { brand: TinkerForge, description: { generic: WARP2 Pro + Energy Manager } }
|
||||
capabilities: ["mA", "1p3p", "rfid"]
|
||||
requirements:
|
||||
description:
|
||||
en: Firmware v2 required. Automatic phase switching requires the additional WARP Energy Manager.
|
||||
de: Firmware v2 erforderlich. Für automatische Phasenumschaltung wird zusätzlich der WARP Energy Manager benötigt.
|
||||
de: Firmware v2 erforderlich. Die WARP-eigene automatische Phasenumschaltung wird von EVCC beim Verbinden mit der Wallbox deaktiviert. Siehe [docs.warp-charger.com](https://docs.warp-charger.com/docs/mqtt_http/api_reference/evse#evse_phase_auto_switch_warp3).
|
||||
en: Firmware v2 required. WARP's own automatic phase switching will be deactivated by EVCC when connecting to the wallbox. See [docs.warp-charger.com](https://docs.warp-charger.com/docs/mqtt_http/api_reference/evse#evse_phase_auto_switch_warp3).
|
||||
evcc: ["skiptest"]
|
||||
params:
|
||||
- name: uri
|
||||
required: true
|
||||
- name: user
|
||||
- name: password
|
||||
- name: energyMeterIndex
|
||||
advanced: true
|
||||
default: 0
|
||||
description:
|
||||
generic: Energy Meter Index
|
||||
help:
|
||||
de: Index des in der Warp konfigurierten Meters dessen Werte genutzt werden sollen.
|
||||
en: Index of the meter configured in the WARP charger whose values should be used.
|
||||
- name: energyManagerUri
|
||||
description:
|
||||
generic: Energy Manager URI
|
||||
|
|
@ -41,4 +49,5 @@ render: |
|
|||
energyManagerUri: {{ .energyManagerUri }}
|
||||
energyManagerUser: {{ .energyManagerUser }}
|
||||
energyManagerPassword: {{ .energyManagerPassword }}
|
||||
energyMeterIndex: {{ .energyMeterIndex }}
|
||||
disablePhaseAutoSwitch: true
|
||||
Loading…
Add table
Add a link
Reference in a new issue