d4c08467cb
Signed-off-by: Thomas Klaehn <tkl@blackfinn.de>
97 lines
2.5 KiB
Go
97 lines
2.5 KiB
Go
package api
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"io"
|
|
"net/http"
|
|
"time"
|
|
)
|
|
|
|
type ChargerStatus struct {
|
|
Car int `json:"car"`
|
|
Frc int `json:"frc"`
|
|
SessionWh float64 `json:"session_wh"`
|
|
Amp int `json:"amp"`
|
|
Soc int `json:"soc"` // car battery %, 0 = not reported by car
|
|
}
|
|
|
|
type goeStatus struct {
|
|
Car int `json:"car"`
|
|
Frc int `json:"frc"`
|
|
Wh float64 `json:"wh"`
|
|
Amp int `json:"amp"`
|
|
Soc int `json:"soc"`
|
|
}
|
|
|
|
var chargerHTTP = &http.Client{Timeout: 5 * time.Second}
|
|
|
|
func fetchChargerStatus(host string) (ChargerStatus, error) {
|
|
url := "http://" + host + "/api/status?filter=car,frc,wh,amp,soc"
|
|
resp, err := chargerHTTP.Get(url)
|
|
if err != nil {
|
|
return ChargerStatus{}, fmt.Errorf("charger unreachable: %w", err)
|
|
}
|
|
defer resp.Body.Close()
|
|
body, err := io.ReadAll(resp.Body)
|
|
if err != nil {
|
|
return ChargerStatus{}, err
|
|
}
|
|
var s goeStatus
|
|
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
|
|
}
|
|
|
|
func setChargerFrc(host string, frc int) error {
|
|
url := fmt.Sprintf("http://%s/api/set?frc=%d", host, frc)
|
|
resp, err := chargerHTTP.Get(url)
|
|
if err != nil {
|
|
return fmt.Errorf("charger unreachable: %w", err)
|
|
}
|
|
defer resp.Body.Close()
|
|
return nil
|
|
}
|
|
|
|
func setChargerAmp(host string, amps int) error {
|
|
url := fmt.Sprintf("http://%s/api/set?amp=%d", host, amps)
|
|
resp, err := chargerHTTP.Get(url)
|
|
if err != nil {
|
|
return fmt.Errorf("charger unreachable: %w", err)
|
|
}
|
|
defer resp.Body.Close()
|
|
return nil
|
|
}
|
|
|
|
// 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.
|
|
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)
|
|
if _, err := fetchChargerStatus(host); err != nil {
|
|
return fmt.Errorf("charger did not recover from reset: %w", err)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// setChargerPhases switches between 1-phase (psm=1) and 3-phase (psm=2).
|
|
// Requires phase-switching hardware in the charger.
|
|
func setChargerPhases(host string, phases int) error {
|
|
psm := 2
|
|
if phases == 1 {
|
|
psm = 1
|
|
}
|
|
url := fmt.Sprintf("http://%s/api/set?psm=%d", host, psm)
|
|
resp, err := chargerHTTP.Get(url)
|
|
if err != nil {
|
|
return fmt.Errorf("charger unreachable: %w", err)
|
|
}
|
|
defer resp.Body.Close()
|
|
return nil
|
|
}
|