diff --git a/charger/heidelberg-ec.go b/charger/heidelberg-ec.go index 60c240e65..79ac0971b 100644 --- a/charger/heidelberg-ec.go +++ b/charger/heidelberg-ec.go @@ -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. @@ -31,16 +32,20 @@ import ( type HeidelbergEC struct { conn *modbus.Connection current uint16 + wakeup bool } const ( - hecRegFirmware = 1 // Input - hecRegVehicleStatus = 5 // Input - hecRegTemperature = 9 // Input - hecRegPower = 14 // Input - hecRegEnergy = 17 // Input - hecRegStandby = 258 // Holding - hecRegAmpsConfig = 261 // Holding + hecRegFirmware = 1 // Input + hecRegVehicleStatus = 5 // Input + hecRegTemperature = 9 // Input + hecRegPower = 14 // Input + hecRegEnergy = 17 // Input + hecRegTimeoutConfig = 257 // Holding + hecRegStandbyConfig = 258 // Holding + hecRegRemoteLock = 259 // Holding + hecRegAmpsConfig = 261 // Holding + hecRegFailSafeConfig = 262 // Holding hecStandbyDisabled = 4 // disable standby ) @@ -86,8 +91,8 @@ func NewHeidelbergEC(uri, device, comset string, baudrate int, proto modbus.Prot current: 60, // assume min current } - // disable standby - err = wb.set(hecRegStandby, hecStandbyDisabled) + // disable standby to prevent comm loss + err = wb.set(hecRegStandbyConfig, hecStandbyDisabled) return wb, err } @@ -108,13 +113,29 @@ func (wb *HeidelbergEC) Status() (api.ChargeStatus, error) { return api.StatusNone, err } - switch sb := b[1]; sb { + sb := binary.BigEndian.Uint16(b) + + if sb != 10 { + wb.wakeup = false + } + + switch sb { case 2, 3: return api.StatusA, nil case 4, 5: return api.StatusB, nil case 6, 7: return api.StatusC, nil + case 8: + return api.StatusD, nil + case 9: + return api.StatusE, nil + case 10: + if wb.wakeup { + // Keep Status B2 during Wakeup + return api.StatusB, nil + } + return api.StatusF, nil default: return api.StatusNone, fmt.Errorf("invalid status: %d", sb) } @@ -233,7 +254,32 @@ func (wb *HeidelbergEC) Diagnose() { if b, err := wb.conn.ReadInputRegisters(hecRegTemperature, 1); err == nil { fmt.Printf("Temperature:\t%.1fC\n", float64(int16(binary.BigEndian.Uint16(b)))/10) } - if b, err := wb.conn.ReadHoldingRegisters(hecRegStandby, 1); err == nil { - fmt.Printf("Standby:\t%0x\n", b[1]) + if b, err := wb.conn.ReadHoldingRegisters(hecRegTimeoutConfig, 1); err == nil { + fmt.Printf("Timeout:\t%d\n", binary.BigEndian.Uint16(b)) + } + if b, err := wb.conn.ReadHoldingRegisters(hecRegStandbyConfig, 1); err == nil { + fmt.Printf("Standby:\t%d\n", binary.BigEndian.Uint16(b)) + } + if b, err := wb.conn.ReadHoldingRegisters(hecRegRemoteLock, 1); err == nil { + fmt.Printf("Remote Lock:\t%d\n", binary.BigEndian.Uint16(b)) + } + if b, err := wb.conn.ReadHoldingRegisters(hecRegFailSafeConfig, 1); err == nil { + fmt.Printf("FailSafe:\t%d\n", binary.BigEndian.Uint16(b)) } } + +var _ api.AlarmClock = (*HeidelbergEC)(nil) + +// WakeUp implements the api.AlarmClock interface +func (wb *HeidelbergEC) WakeUp() error { + // Force Status F by locking + err := wb.set(hecRegRemoteLock, 0) + if err == nil { + // Always takes at least ~10 sec to return to normal operation + // after locking even if unlocking immediately. + wb.wakeup = true + // Return to normal operation by unlocking after ~10 sec + err = wb.set(hecRegRemoteLock, 1) + } + return err +}