Phoenix: fix measurement scaling (#21726)
This commit is contained in:
parent
c65f1acd5a
commit
08a5e9600a
2 changed files with 69 additions and 34 deletions
|
|
@ -145,36 +145,22 @@ func (wb *PhoenixEMEth) ChargeDuration() (time.Duration, error) {
|
|||
}
|
||||
|
||||
// CurrentPower implements the api.Meter interface
|
||||
func (wb *PhoenixEMEth) readScaledValue(regValue, regScale uint16) (int32, float64, error) {
|
||||
bValue, err := wb.conn.ReadInputRegisters(regValue, 2)
|
||||
if err != nil {
|
||||
return 0, 0, err
|
||||
}
|
||||
bScale, err := wb.conn.ReadHoldingRegisters(regScale, 2)
|
||||
if err != nil {
|
||||
return 0, 0, err
|
||||
}
|
||||
scale := 1000.0 * rs485.RTUIeee754ToFloat64Swapped(bScale)
|
||||
|
||||
return encoding.Int32LswFirst(bValue), scale, nil
|
||||
}
|
||||
|
||||
func (wb *PhoenixEMEth) currentPower() (float64, error) {
|
||||
value, scale, err := wb.readScaledValue(phxEMEthRegPower, phxEMEthRegPowerScale)
|
||||
value, err := wb.readScaledValue(phxEMEthRegPower, phxEMEthRegPowerScale)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return float64(value) / scale, nil
|
||||
return value, nil
|
||||
}
|
||||
|
||||
func (wb *PhoenixEMEth) totalEnergy() (float64, error) {
|
||||
value, scale, err := wb.readScaledValue(phxEMEthRegEnergy, phxEMEthRegEnergyScale)
|
||||
value, err := wb.readScaledValue(phxEMEthRegEnergy, phxEMEthRegEnergyScale)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return float64(value) / scale, nil
|
||||
return value, nil
|
||||
}
|
||||
|
||||
// currents implements the api.PhaseCurrents interface
|
||||
|
|
@ -187,6 +173,20 @@ func (wb *PhoenixEMEth) voltages() (float64, float64, float64, error) {
|
|||
return wb.getPhaseValues(phxEMEthRegVoltages, phxEMEthRegVoltagesScale)
|
||||
}
|
||||
|
||||
func (wb *PhoenixEMEth) readScaledValue(regValue, regScale uint16) (float64, error) {
|
||||
bValue, err := wb.conn.ReadInputRegisters(regValue, 2)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
bScale, err := wb.conn.ReadHoldingRegisters(regScale, 2)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
scale := rs485.RTUIeee754ToFloat64Swapped(bScale) / 1000.0
|
||||
|
||||
return float64(encoding.Int32LswFirst(bValue)) * scale, nil
|
||||
}
|
||||
|
||||
func (wb *PhoenixEMEth) readScaledValues(regValue, regScale uint16) ([]float64, error) {
|
||||
const count = 3
|
||||
|
||||
|
|
@ -201,8 +201,8 @@ func (wb *PhoenixEMEth) readScaledValues(regValue, regScale uint16) ([]float64,
|
|||
|
||||
res := make([]float64, count)
|
||||
for i := 0; i < count; i++ {
|
||||
scale := 1000.0 * rs485.RTUIeee754ToFloat64Swapped(bScale[4*i:])
|
||||
res[i] = float64(encoding.Int32LswFirst(bValue[4*i:])) / scale
|
||||
scale := rs485.RTUIeee754ToFloat64Swapped(bScale[4*i:]) / 1000.0
|
||||
res[i] = float64(encoding.Int32LswFirst(bValue[4*i:])) * scale
|
||||
}
|
||||
|
||||
return res, nil
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ package charger
|
|||
|
||||
// LICENSE
|
||||
|
||||
// Copyright (c) 2023 premultiply
|
||||
// Copyright (c) 2023-2025 premultiply
|
||||
|
||||
// This module is NOT covered by the MIT license. All rights reserved.
|
||||
|
||||
|
|
@ -32,6 +32,7 @@ import (
|
|||
"github.com/evcc-io/evcc/util/modbus"
|
||||
"github.com/evcc-io/evcc/util/sponsor"
|
||||
"github.com/volkszaehler/mbmd/encoding"
|
||||
"github.com/volkszaehler/mbmd/meters/rs485"
|
||||
)
|
||||
|
||||
type PhoenixEVEth struct {
|
||||
|
|
@ -49,6 +50,10 @@ const (
|
|||
phxRegEnergy = 128 // Input
|
||||
phxRegChargedEnergy = 132 // Input
|
||||
phxRegFirmwareWallbe = 149 // Input
|
||||
phxRegVoltagesScale = 352 // Holding
|
||||
phxRegCurrentsScale = 358 // Holding
|
||||
phxRegPowerScale = 364 // Holding
|
||||
phxRegEnergyScale = 372 // Holding
|
||||
phxRegEnable = 400 // Coil
|
||||
phxRegCardEnabled = 419 // Coil
|
||||
phxRegMaxCurrent = 528 // Holding
|
||||
|
|
@ -184,12 +189,12 @@ func (wb *PhoenixEVEth) maxCurrentMillis(current float64) error {
|
|||
|
||||
// currentPower implements the api.Meter interface
|
||||
func (wb *PhoenixEVEth) currentPower() (float64, error) {
|
||||
b, err := wb.conn.ReadInputRegisters(phxRegPower, 2)
|
||||
value, err := wb.readScaledValue(phxRegPower, phxRegPowerScale)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return float64(encoding.Int32LswFirst(b)), nil
|
||||
return value, nil
|
||||
}
|
||||
|
||||
// totalEnergy implements the api.MeterEnergy interface
|
||||
|
|
@ -203,36 +208,66 @@ func (wb *PhoenixEVEth) totalEnergy() (float64, error) {
|
|||
return float64(encoding.Uint64LswFirst(b)) / 1e3, nil
|
||||
}
|
||||
|
||||
b, err := wb.conn.ReadHoldingRegisters(phxRegEnergyWh, 2)
|
||||
value, err := wb.readScaledValue(phxRegEnergy, phxRegEnergyScale)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return float64(encoding.Uint32LswFirst(b)) / 1e3, nil
|
||||
return value, nil
|
||||
}
|
||||
|
||||
// currents implements the api.PhaseCurrents interface
|
||||
func (wb *PhoenixEVEth) currents() (float64, float64, float64, error) {
|
||||
return wb.getPhaseValues(phxRegCurrents)
|
||||
return wb.getPhaseValues(phxRegCurrents, phxRegCurrentsScale)
|
||||
}
|
||||
|
||||
// voltages implements the api.PhaseVoltages interface
|
||||
func (wb *PhoenixEVEth) voltages() (float64, float64, float64, error) {
|
||||
return wb.getPhaseValues(phxRegVoltages)
|
||||
return wb.getPhaseValues(phxRegVoltages, phxRegVoltagesScale)
|
||||
}
|
||||
|
||||
func (wb *PhoenixEVEth) readScaledValue(regValue, regScale uint16) (float64, error) {
|
||||
bValue, err := wb.conn.ReadInputRegisters(regValue, 2)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
bScale, err := wb.conn.ReadHoldingRegisters(regScale, 2)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
scale := rs485.RTUIeee754ToFloat64Swapped(bScale) / 1000.0
|
||||
|
||||
return float64(encoding.Int32LswFirst(bValue)) * scale, nil
|
||||
}
|
||||
|
||||
func (wb *PhoenixEVEth) readScaledValues(regValue, regScale uint16) ([]float64, error) {
|
||||
const count = 3
|
||||
|
||||
bValue, err := wb.conn.ReadInputRegisters(regValue, uint16(2*count))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
bScale, err := wb.conn.ReadHoldingRegisters(regScale, uint16(2*count))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
res := make([]float64, count)
|
||||
for i := 0; i < count; i++ {
|
||||
scale := rs485.RTUIeee754ToFloat64Swapped(bScale[4*i:]) / 1000.0
|
||||
res[i] = float64(encoding.Int32LswFirst(bValue[4*i:])) * scale
|
||||
}
|
||||
|
||||
return res, nil
|
||||
}
|
||||
|
||||
// getPhaseValues returns 3 sequential phase values
|
||||
func (wb *PhoenixEVEth) getPhaseValues(reg uint16) (float64, float64, float64, error) {
|
||||
b, err := wb.conn.ReadInputRegisters(reg, 6)
|
||||
func (wb *PhoenixEVEth) getPhaseValues(regValue, regScale uint16) (float64, float64, float64, error) {
|
||||
res, err := wb.readScaledValues(regValue, regScale)
|
||||
if err != nil {
|
||||
return 0, 0, 0, err
|
||||
}
|
||||
|
||||
var res [3]float64
|
||||
for i := range res {
|
||||
res[i] = float64(encoding.Int32LswFirst(b[4*i:]))
|
||||
}
|
||||
|
||||
return res[0], res[1], res[2], nil
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue