ABL: Add wakeup (#2883)
This commit is contained in:
parent
3d9be7b157
commit
e6b31626d8
1 changed files with 64 additions and 28 deletions
|
|
@ -3,6 +3,7 @@ package charger
|
|||
// LICENSE
|
||||
|
||||
// Copyright (c) 2019-2022 andig
|
||||
// Copyright (c) 2022 premultiply
|
||||
|
||||
// This module is NOT covered by the MIT license. All rights reserved.
|
||||
|
||||
|
|
@ -20,6 +21,7 @@ package charger
|
|||
import (
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/evcc-io/evcc/api"
|
||||
"github.com/evcc-io/evcc/util"
|
||||
|
|
@ -34,14 +36,16 @@ type ABLeMH struct {
|
|||
}
|
||||
|
||||
const (
|
||||
ablRegFirmware = 0x01
|
||||
ablRegStatus = 0x04
|
||||
ablRegEnabled = 0x0F
|
||||
ablRegAmpsConfig = 0x14
|
||||
ablRegStatusLong = 0x2E
|
||||
ablRegFirmware = 0x01
|
||||
ablRegStatus = 0x04
|
||||
ablRegModifyState = 0x05
|
||||
ablRegEnabled = 0x0F
|
||||
ablRegAmpsConfig = 0x14
|
||||
ablRegStatusLong = 0x2E
|
||||
|
||||
ablAmpsDisabled uint16 = 0x03E8
|
||||
ablSensorPresent = 1 << 5
|
||||
ablAmpsDisabled uint16 = 0x03E8
|
||||
|
||||
ablSensorPresent = 1 << 5
|
||||
)
|
||||
|
||||
var ablStatus = map[byte]string{
|
||||
|
|
@ -108,8 +112,7 @@ func NewABLeMH(uri, device, comset string, baudrate int, slaveID uint8) (api.Cha
|
|||
curr: uint16(6 / 0.06),
|
||||
}
|
||||
|
||||
_, _ = wb.conn.ReadHoldingRegisters(ablRegFirmware, 2)
|
||||
b, err := wb.conn.ReadHoldingRegisters(ablRegFirmware, 2)
|
||||
b, err := wb.get(ablRegFirmware, 2)
|
||||
|
||||
// check presence of current sensor
|
||||
if err == nil && (b[3]&ablSensorPresent != 0) {
|
||||
|
|
@ -119,10 +122,28 @@ func NewABLeMH(uri, device, comset string, baudrate int, slaveID uint8) (api.Cha
|
|||
return wb, err
|
||||
}
|
||||
|
||||
func (wb *ABLeMH) set(reg, val uint16) error {
|
||||
b := make([]byte, 2)
|
||||
binary.BigEndian.PutUint16(b, val)
|
||||
|
||||
//write two times
|
||||
_, _ = wb.conn.WriteMultipleRegisters(reg, 1, b)
|
||||
_, err := wb.conn.WriteMultipleRegisters(reg, 1, b)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func (wb *ABLeMH) get(reg, count uint16) ([]byte, error) {
|
||||
//read two times
|
||||
_, _ = wb.conn.ReadHoldingRegisters(reg, count)
|
||||
b, err := wb.conn.ReadHoldingRegisters(reg, count)
|
||||
|
||||
return b, err
|
||||
}
|
||||
|
||||
// Status implements the api.Charger interface
|
||||
func (wb *ABLeMH) Status() (api.ChargeStatus, error) {
|
||||
_, _ = wb.conn.ReadHoldingRegisters(ablRegStatus, 1)
|
||||
b, err := wb.conn.ReadHoldingRegisters(ablRegStatus, 1)
|
||||
b, err := wb.get(ablRegStatus, 1)
|
||||
if err != nil {
|
||||
return api.StatusNone, err
|
||||
}
|
||||
|
|
@ -144,8 +165,7 @@ func (wb *ABLeMH) Status() (api.ChargeStatus, error) {
|
|||
|
||||
// Enabled implements the api.Charger interface
|
||||
func (wb *ABLeMH) Enabled() (bool, error) {
|
||||
_, _ = wb.conn.ReadHoldingRegisters(ablRegEnabled, 5)
|
||||
b, err := wb.conn.ReadHoldingRegisters(ablRegEnabled, 5)
|
||||
b, err := wb.get(ablRegEnabled, 5)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
|
@ -161,17 +181,17 @@ func (wb *ABLeMH) Enable(enable bool) error {
|
|||
u = wb.curr
|
||||
}
|
||||
|
||||
b := make([]byte, 2)
|
||||
binary.BigEndian.PutUint16(b, u)
|
||||
|
||||
_, _ = wb.conn.WriteMultipleRegisters(ablRegAmpsConfig, 1, b)
|
||||
_, err := wb.conn.WriteMultipleRegisters(ablRegAmpsConfig, 1, b)
|
||||
err := wb.set(ablRegAmpsConfig, u)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// MaxCurrent implements the api.Charger interface
|
||||
func (wb *ABLeMH) MaxCurrent(current int64) error {
|
||||
if current < 6 {
|
||||
return fmt.Errorf("invalid current %d", current)
|
||||
}
|
||||
|
||||
return wb.MaxCurrentMillis(float64(current))
|
||||
}
|
||||
|
||||
|
|
@ -179,14 +199,17 @@ var _ api.ChargerEx = (*ABLeMH)(nil)
|
|||
|
||||
// MaxCurrent implements the api.ChargerEx interface
|
||||
func (wb *ABLeMH) MaxCurrentMillis(current float64) error {
|
||||
if current < 6 {
|
||||
return fmt.Errorf("invalid current %.1f", current)
|
||||
}
|
||||
|
||||
// calculate duty cycle according to https://www.goingelectric.de/forum/viewtopic.php?p=1575287#p1575287
|
||||
wb.curr = uint16(current / 0.06)
|
||||
cur := uint16(current / 0.06)
|
||||
|
||||
b := make([]byte, 2)
|
||||
binary.BigEndian.PutUint16(b, wb.curr)
|
||||
|
||||
_, _ = wb.conn.WriteMultipleRegisters(ablRegAmpsConfig, 1, b)
|
||||
_, err := wb.conn.WriteMultipleRegisters(ablRegAmpsConfig, 1, b)
|
||||
err := wb.set(ablRegAmpsConfig, cur)
|
||||
if err == nil {
|
||||
wb.curr = cur
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
|
@ -199,8 +222,7 @@ func (wb *ABLeMH) currentPower() (float64, error) {
|
|||
|
||||
// Currents implements the api.MeterCurrent interface
|
||||
func (wb *ABLeMH) currents() (float64, float64, float64, error) {
|
||||
_, _ = wb.conn.ReadHoldingRegisters(ablRegStatusLong, 5)
|
||||
b, err := wb.conn.ReadHoldingRegisters(ablRegStatusLong, 5)
|
||||
b, err := wb.get(ablRegStatusLong, 5)
|
||||
if err != nil {
|
||||
return 0, 0, 0, err
|
||||
}
|
||||
|
|
@ -222,9 +244,23 @@ var _ api.Diagnosis = (*ABLeMH)(nil)
|
|||
|
||||
// Diagnose implements the api.Diagnosis interface
|
||||
func (wb *ABLeMH) Diagnose() {
|
||||
_, _ = wb.conn.ReadHoldingRegisters(ablRegFirmware, 2)
|
||||
b, err := wb.conn.ReadHoldingRegisters(ablRegFirmware, 2)
|
||||
b, err := wb.get(ablRegFirmware, 2)
|
||||
if err == nil {
|
||||
fmt.Printf("Firmware: %0 x\n", b)
|
||||
}
|
||||
}
|
||||
|
||||
var _ api.AlarmClock = (*ABLeMH)(nil)
|
||||
|
||||
// WakeUp implements the api.AlarmClock interface
|
||||
func (wb *ABLeMH) WakeUp() error {
|
||||
// temporary jump to status E0 (Outlet disabled)
|
||||
err := wb.set(ablRegModifyState, 0xE0E0)
|
||||
if err == nil {
|
||||
time.Sleep(3 * time.Second)
|
||||
// jump back to state A1 (Waiting for EV)
|
||||
err = wb.set(ablRegModifyState, 0xA1A1)
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue