Fix: authorize by RFID or WebUI
This commit is contained in:
@@ -46,12 +46,29 @@ type ChargerController struct {
|
||||
}
|
||||
|
||||
func NewChargerController(host string, pool *pgxpool.Pool) *ChargerController {
|
||||
return &ChargerController{
|
||||
c := &ChargerController{
|
||||
host: host,
|
||||
pool: pool,
|
||||
params: ChargingParams{Mode: ModeOff},
|
||||
status: "idle",
|
||||
status: "initializing",
|
||||
}
|
||||
// Always restore RFID-gated idle state on startup. nmo/acs settings persist
|
||||
// on the charger hardware across app restarts, so we must reset them explicitly.
|
||||
go c.initSafeState()
|
||||
return c
|
||||
}
|
||||
|
||||
func (c *ChargerController) initSafeState() {
|
||||
if err := setChargerFrc(c.host, 1); err != nil {
|
||||
log.Printf("charger ctrl: init: %v", err)
|
||||
c.setStatus("charger unreachable")
|
||||
return
|
||||
}
|
||||
setChargerNmo(c.host, false)
|
||||
setChargerAcs(c.host, 1)
|
||||
setChargerFrc(c.host, 0)
|
||||
c.setStatus("idle")
|
||||
log.Printf("charger ctrl: initialized — RFID-gated (nmo=false, acs=1)")
|
||||
}
|
||||
|
||||
func (c *ChargerController) State() ControllerState {
|
||||
@@ -131,12 +148,15 @@ func (c *ChargerController) enableCharging(amps int) error {
|
||||
if err != nil {
|
||||
return fmt.Errorf("charger unreachable: %w", err)
|
||||
}
|
||||
if st.Car == 4 {
|
||||
c.setStatus("resetting — previous session complete")
|
||||
// car=4: previous session must be cleared before a new one can start.
|
||||
// car=3: car entered IEC state B while acs=1 was active; the CP-line
|
||||
// "wait for auth" signal means the car won't accept frc=2 alone —
|
||||
// a full reset forces a fresh IEC 61851 handshake.
|
||||
if st.Car == 4 || st.Car == 3 {
|
||||
c.setStatus("resetting — fresh IEC negotiation needed")
|
||||
if err := resetCharger(c.host); err != nil {
|
||||
return fmt.Errorf("reset: %w", err)
|
||||
}
|
||||
// Reset clears currentPhases so phase-switch logic starts fresh
|
||||
c.mu.Lock()
|
||||
c.currentPhases = 0
|
||||
c.mu.Unlock()
|
||||
@@ -276,6 +296,24 @@ func (c *ChargerController) adjust(ctx context.Context) {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// frc=2 alone does not override acs=1 on this firmware: if access control
|
||||
// is still blocking (alw=false) and we haven't intentionally force-paused
|
||||
// (frc=1), the session hasn't been authorised yet — call enableCharging to
|
||||
// set acs=0 and start the session properly.
|
||||
// Guard on battPaused: if the battery SOC is already below the cutoff
|
||||
// (set at the top of this function), do not enable charging even if the
|
||||
// charger looks idle — the pause takes priority.
|
||||
c.mu.RLock()
|
||||
paused := c.battPaused
|
||||
c.mu.RUnlock()
|
||||
if !st.Alw && st.Frc != 1 && !paused {
|
||||
if err := c.enableCharging(params.MaxAmp); err != nil {
|
||||
log.Printf("charger ctrl: session start: %v", err)
|
||||
c.setStatus("session start failed: " + err.Error())
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// Grid mode: current is fixed and already applied by enableCharging(); the
|
||||
@@ -412,7 +450,16 @@ func (c *ChargerController) stopOnDisconnect() {
|
||||
|
||||
func (c *ChargerController) stopForTarget(reason string) {
|
||||
if err := setChargerFrc(c.host, 1); err != nil {
|
||||
log.Printf("charger ctrl: stop: %v", err)
|
||||
log.Printf("charger ctrl: stop frc1: %v", err)
|
||||
}
|
||||
if err := setChargerNmo(c.host, false); err != nil {
|
||||
log.Printf("charger ctrl: stop nmo: %v", err)
|
||||
}
|
||||
if err := setChargerAcs(c.host, 1); err != nil {
|
||||
log.Printf("charger ctrl: stop acs: %v", err)
|
||||
}
|
||||
if err := setChargerFrc(c.host, 0); err != nil {
|
||||
log.Printf("charger ctrl: stop frc0: %v", err)
|
||||
}
|
||||
c.mu.Lock()
|
||||
c.params.Mode = ModeOff
|
||||
|
||||
Reference in New Issue
Block a user