Add support for electric vehicles

Signed-off-by: Knut Ahlers <knut@ahlers.me>
This commit is contained in:
Knut Ahlers 2022-12-04 00:22:53 +01:00
parent 6d438d912a
commit b51d41f15e
Signed by: luzifer
GPG key ID: D91C3E91E4CAD6F5
8 changed files with 92 additions and 14 deletions

View file

@ -46,5 +46,12 @@ func runFetcher(mc mercedes.Client, vehicleID string) {
}
enabledExporters.SetLockStatus(vehicleID, s4)
s5, err := mc.GetElectricStatus(cfg.VehicleID[0])
if err != nil {
logger.WithError(err).Error("fetching electric-status data")
return
}
enabledExporters.SetElectricStatus(vehicleID, s5)
logger.Info("data updated successfully")
}

View file

@ -12,12 +12,18 @@ const (
labelLight = "light"
labelWindow = "window"
subsystemFuelStatus = "fuel_status"
subsystemLockStatus = "lock_status"
subsystemPayAsYouDrive = "pay_as_you_drive"
subsystemVehicleStatus = "vehicle_status"
subsystemElectricStatus = `electric_status`
subsystemFuelStatus = "fuel_status"
subsystemLockStatus = "lock_status"
subsystemPayAsYouDrive = "pay_as_you_drive"
subsystemVehicleStatus = "vehicle_status"
)
func (e *Exporter) SetElectricStatus(vehicleID string, es mercedes.ElectricStatus) {
e.submitValue(es.ElectricRange, mn(subsystemElectricStatus, "electric_range"), labelVehicleID, vehicleID)
e.submitValue(es.StateOfCharge, mn(subsystemElectricStatus, "state_of_charge"), labelVehicleID, vehicleID)
}
func (e *Exporter) SetFuelStatus(vehicleID string, fs mercedes.FuelStatus) {
e.submitValue(fs.RangeLiquid, mn(subsystemFuelStatus, "range_liquid"), labelVehicleID, vehicleID)
e.submitValue(fs.TanklevelPercent, mn(subsystemFuelStatus, "tanklevel_percent"), labelVehicleID, vehicleID)

View file

@ -4,6 +4,7 @@ import "github.com/Luzifer/mercedes-byocar-exporter/internal/mercedes"
type (
Exporter interface {
SetElectricStatus(vehicleID string, es mercedes.ElectricStatus)
SetFuelStatus(vehicleID string, fs mercedes.FuelStatus)
SetLockStatus(vehicleID string, ls mercedes.LockStatus)
SetPayAsYouGo(vehicleID string, p mercedes.PayAsYouDriveInsurance)
@ -15,6 +16,12 @@ type (
var _ Exporter = Set{}
func (s Set) SetElectricStatus(vehicleID string, es mercedes.ElectricStatus) {
for _, e := range s {
e.SetElectricStatus(vehicleID, es)
}
}
func (s Set) SetFuelStatus(vehicleID string, fs mercedes.FuelStatus) {
for _, e := range s {
e.SetFuelStatus(vehicleID, fs)

View file

@ -13,13 +13,17 @@ const (
metricsNamespace = "mercedes_byocar"
subsystemFuelStatus = "fuel_status"
subsystemLockStatus = "lock_status"
subsystemPayAsYouDrive = "pay_as_you_drive"
subsystemVehicleStatus = "vehicle_status"
subsystemElectricStatus = `electric_status`
subsystemFuelStatus = "fuel_status"
subsystemLockStatus = "lock_status"
subsystemPayAsYouDrive = "pay_as_you_drive"
subsystemVehicleStatus = "vehicle_status"
)
var (
electricSOC *prometheus.GaugeVec
electricRange *prometheus.GaugeVec
fuelRangeLiquidVec *prometheus.GaugeVec
fuelTanklevelPercent *prometheus.GaugeVec
@ -41,12 +45,29 @@ var (
)
func init() {
initElectricStatus()
initFuelStatus()
initLockStatus()
initPAYD()
initVehicleStatus()
}
func initElectricStatus() {
electricRange = promauto.NewGaugeVec(prometheus.GaugeOpts{
Namespace: metricsNamespace,
Subsystem: subsystemElectricStatus,
Name: "electric_range",
Help: "Electric range - 0..2046 km",
}, []string{labelVehicleID})
electricSOC = promauto.NewGaugeVec(prometheus.GaugeOpts{
Namespace: metricsNamespace,
Subsystem: subsystemElectricStatus,
Name: "state_of_charge",
Help: "Displayed state of charge for the HV battery - 0..100 %",
}, []string{labelVehicleID})
}
func initFuelStatus() {
fuelRangeLiquidVec = promauto.NewGaugeVec(prometheus.GaugeOpts{
Namespace: metricsNamespace,

View file

@ -16,6 +16,11 @@ var (
_ exporters.Exporter = exporter{}
)
func (exporter) SetElectricStatus(vehicleID string, es mercedes.ElectricStatus) {
setGaugeVecValue(es.ElectricRange, electricRange, labelVehicleID, vehicleID)
setGaugeVecValue(es.StateOfCharge, electricSOC, labelVehicleID, vehicleID)
}
func (exporter) SetFuelStatus(vehicleID string, fs mercedes.FuelStatus) {
setGaugeVecValue(fs.RangeLiquid, fuelRangeLiquidVec, labelVehicleID, vehicleID)
setGaugeVecValue(fs.TanklevelPercent, fuelTanklevelPercent, labelVehicleID, vehicleID)

View file

@ -9,6 +9,7 @@ import (
type (
Client interface {
GetAuthStartURL(redirectURL string) string
GetElectricStatus(vehicleID string) (ElectricStatus, error)
GetFuelStatus(vehicleID string) (FuelStatus, error)
GetLockStatus(vehicleID string) (LockStatus, error)
GetPayAsYouDriveInsurance(vehicleID string) (PayAsYouDriveInsurance, error)
@ -64,12 +65,13 @@ const (
oAuthEndpointAuth = "https://ssoalpha.dvb.corpinter.net/v1/auth"
oAuthEndpointToken = "https://ssoalpha.dvb.corpinter.net/v1/token"
oAuthScopeOfflineAccess = "offline_access"
oAuthScopeOpenID = "openid"
oAuthScopePayAsYouDrive = "mb:vehicle:mbdata:payasyoudrive"
oAuthScopeVehicleFuelStatus = "mb:vehicle:mbdata:fuelstatus"
oAuthScopeVehicleLockStatus = "mb:vehicle:mbdata:vehiclelock"
oAuthScopeVehicleStatus = "mb:vehicle:mbdata:vehiclestatus"
oAuthScopeOfflineAccess = "offline_access"
oAuthScopeOpenID = "openid"
oAuthScopePayAsYouDrive = "mb:vehicle:mbdata:payasyoudrive"
oAuthScopeVehicleElectricStatus = "mb:vehicle:mbdata:evstatus"
oAuthScopeVehicleFuelStatus = "mb:vehicle:mbdata:fuelstatus"
oAuthScopeVehicleLockStatus = "mb:vehicle:mbdata:vehiclelock"
oAuthScopeVehicleStatus = "mb:vehicle:mbdata:vehiclestatus"
)
func (g genericAPIResponse) Get(key string) *metricValue {

View file

@ -0,0 +1,29 @@
package mercedes
import (
"fmt"
"github.com/pkg/errors"
)
type (
ElectricStatus struct {
// Displayed state of charge for the HV battery 0..100 %
StateOfCharge TimedInt `apiField:"soc"`
// Electric range 0..2046 km
ElectricRange TimedInt `apiField:"rangeelectric"`
}
)
func (a APIClient) GetElectricStatus(vehicleID string) (ElectricStatus, error) {
var (
path = fmt.Sprintf("/vehicles/%s/containers/electricvehicle", vehicleID)
out ElectricStatus
)
if err := a.request(path, &out); err != nil {
return out, errors.Wrap(err, "getting electric status")
}
return out, nil
}

View file

@ -83,6 +83,7 @@ func (a APIClient) getOauth2Config(redirectURL string) *oauth2.Config {
oAuthScopeOfflineAccess,
oAuthScopeOpenID,
oAuthScopePayAsYouDrive,
oAuthScopeVehicleElectricStatus,
oAuthScopeVehicleFuelStatus,
oAuthScopeVehicleLockStatus,
oAuthScopeVehicleStatus,