improve wall box integration

Signed-off-by: Thomas Klaehn <tkl@blackfinn.de>
This commit is contained in:
2026-05-21 11:41:58 +02:00
parent d4c08467cb
commit ca51807d92
4 changed files with 220 additions and 42 deletions
+46 -5
View File
@@ -14,6 +14,7 @@ type ChargerStatus struct {
SessionWh float64 `json:"session_wh"`
Amp int `json:"amp"`
Soc int `json:"soc"` // car battery %, 0 = not reported by car
Alw bool `json:"alw"` // charging allowed (false = access control blocking)
}
type goeStatus struct {
@@ -22,12 +23,13 @@ type goeStatus struct {
Wh float64 `json:"wh"`
Amp int `json:"amp"`
Soc int `json:"soc"`
Alw bool `json:"alw"`
}
var chargerHTTP = &http.Client{Timeout: 5 * time.Second}
var chargerHTTP = &http.Client{Timeout: 15 * time.Second}
func fetchChargerStatus(host string) (ChargerStatus, error) {
url := "http://" + host + "/api/status?filter=car,frc,wh,amp,soc"
url := "http://" + host + "/api/status?filter=car,frc,wh,amp,soc,alw"
resp, err := chargerHTTP.Get(url)
if err != nil {
return ChargerStatus{}, fmt.Errorf("charger unreachable: %w", err)
@@ -41,7 +43,46 @@ func fetchChargerStatus(host string) (ChargerStatus, error) {
if err := json.Unmarshal(body, &s); err != nil {
return ChargerStatus{}, err
}
return ChargerStatus{Car: s.Car, Frc: s.Frc, SessionWh: s.Wh, Amp: s.Amp, Soc: s.Soc}, nil
return ChargerStatus{Car: s.Car, Frc: s.Frc, SessionWh: s.Wh, Amp: s.Amp, Soc: s.Soc, Alw: s.Alw}, nil
}
// setChargerAcs sets access control: 0 = open (app controls), 1 = RFID required.
func setChargerAcs(host string, acs int) error {
url := fmt.Sprintf("http://%s/api/set?acs=%d", host, acs)
resp, err := chargerHTTP.Get(url)
if err != nil {
return fmt.Errorf("charger unreachable: %w", err)
}
defer resp.Body.Close()
return nil
}
// setChargerNmo sets Norwegian mode: true = charge without RFID, false = normal.
func setChargerNmo(host string, enabled bool) error {
val := "false"
if enabled {
val = "true"
}
url := "http://" + host + "/api/set?nmo=" + val
resp, err := chargerHTTP.Get(url)
if err != nil {
return fmt.Errorf("charger unreachable: %w", err)
}
defer resp.Body.Close()
return nil
}
// setChargerTrx starts a charging session (trx=0). With acs=0 this bypasses
// RFID authentication but still initiates the IEC 61851 handshake — without
// it the charger stays in modelStatus "paused" and never closes its relay.
func setChargerTrx(host string) error {
url := "http://" + host + "/api/set?trx=0"
resp, err := chargerHTTP.Get(url)
if err != nil {
return fmt.Errorf("charger unreachable: %w", err)
}
defer resp.Body.Close()
return nil
}
func setChargerFrc(host string, frc int) error {
@@ -65,14 +106,14 @@ func setChargerAmp(host string, amps int) error {
}
// resetCharger sends rst=1 and waits for the charger to reboot.
// frc is reset to 0 by the charger firmware, so callers must re-apply mode after this.
// frc and trx are cleared by the firmware on reset; callers must re-apply mode after this.
func resetCharger(host string) error {
url := "http://" + host + "/api/set?rst=1"
resp, _ := chargerHTTP.Get(url) // charger may close connection before responding
if resp != nil {
resp.Body.Close()
}
time.Sleep(8 * time.Second)
time.Sleep(12 * time.Second) // v59.x firmware takes longer to reboot
if _, err := fetchChargerStatus(host); err != nil {
return fmt.Errorf("charger did not recover from reset: %w", err)
}