diff --git a/templates/definition/vehicle/seat.yaml b/templates/definition/vehicle/seat.yaml index ba3de730a..2cf4a0332 100644 --- a/templates/definition/vehicle/seat.yaml +++ b/templates/definition/vehicle/seat.yaml @@ -7,6 +7,7 @@ params: - preset: vehicle-base - preset: vehicle-climater render: | - type: seat + type: drivesomethinggreater + brand: Seat {{ include "vehicle-base" . }} {{ include "vehicle-features" . }} diff --git a/vehicle/audi.go b/vehicle/audi.go deleted file mode 100644 index b44d4bd70..000000000 --- a/vehicle/audi.go +++ /dev/null @@ -1,92 +0,0 @@ -package vehicle - -import ( - "context" - "time" - - "github.com/evcc-io/evcc/api" - "github.com/evcc-io/evcc/util" - "github.com/evcc-io/evcc/util/request" - "github.com/evcc-io/evcc/vehicle/audi" - "github.com/evcc-io/evcc/vehicle/vag/idkproxy" - "github.com/evcc-io/evcc/vehicle/vag/service" - "github.com/evcc-io/evcc/vehicle/vag/vwidentity" - "github.com/evcc-io/evcc/vehicle/vw/weconnect" -) - -// https://github.com/TA2k/ioBroker.vw-connect -// https://github.com/arjenvrh/audi_connect_ha/blob/master/custom_components/audiconnect/audi_services.py - -// Audi is an api.Vehicle implementation for Audi cars -type Audi struct { - *embed - *weconnect.Provider // provides the api implementations -} - -func init() { - registry.Add("audi", NewAudiFromConfig) -} - -// NewAudiFromConfig creates a new vehicle -func NewAudiFromConfig(other map[string]any) (api.Vehicle, error) { - cc := struct { - embed `mapstructure:",squash"` - User, Password, VIN string - Cache time.Duration - Timeout time.Duration - }{ - Cache: interval, - Timeout: request.Timeout, - } - - if err := util.DecodeOther(other, &cc); err != nil { - return nil, err - } - - if cc.User == "" || cc.Password == "" { - return nil, api.ErrMissingCredentials - } - - v := &Audi{ - embed: &cc.embed, - } - - log := util.NewLogger("audi").Redact(cc.User, cc.Password, cc.VIN) - - // get initial VW identity id_token - q, err := vwidentity.Login(log, audi.AuthParams, cc.User, cc.Password) - if err != nil { - return nil, err - } - - // exchange initial VW identity id_token for Audi AAZS token - idk := idkproxy.New(log, audi.IDKParams) - ats, its, err := service.AAZSTokenSource(log, idk, audi.AZSConfig, q) - if err != nil { - return nil, err - } - - // use the etron API for list of vehicles - api := audi.NewAPI(log, ats) - - vehicle, err := ensureVehicleEx( - cc.VIN, func() ([]audi.Vehicle, error) { - ctx, cancel := context.WithTimeout(context.Background(), cc.Timeout) - defer cancel() - return api.Vehicles(ctx) - }, - func(v audi.Vehicle) (string, error) { - return v.VIN, nil - }, - ) - - if err == nil { - api := weconnect.NewAPI(log, its) - api.Client.Timeout = cc.Timeout - - v.fromVehicle(vehicle.Nickname, 0) - v.Provider = weconnect.NewProvider(api, vehicle.VIN, cc.Cache) - } - - return v, err -} diff --git a/vehicle/audi/api.go b/vehicle/audi/api.go deleted file mode 100644 index 8fa36e951..000000000 --- a/vehicle/audi/api.go +++ /dev/null @@ -1,43 +0,0 @@ -package audi - -import ( - "context" - - "github.com/evcc-io/evcc/util" - "github.com/evcc-io/evcc/util/request" - "github.com/hasura/go-graphql-client" - "golang.org/x/oauth2" -) - -const ApiURI = "https://app-api.live-my.audi.com/vgql/v1/graphql" - -// API is the VW api client -type API struct { - client *graphql.Client -} - -// NewAPI creates a new api client -func NewAPI(log *util.Logger, ts oauth2.TokenSource) *API { - ctx := context.WithValue( - context.Background(), - oauth2.HTTPClient, - request.NewClient(log), - ) - - v := &API{ - client: graphql.NewClient(ApiURI, oauth2.NewClient(ctx, ts)), - } - - return v -} - -// Vehicles implements the /vehicles response -func (v *API) Vehicles(ctx context.Context) ([]Vehicle, error) { - var res struct { - UserVehicles []Vehicle - } - - err := v.client.Query(ctx, &res, nil) - - return res.UserVehicles, err -} diff --git a/vehicle/audi/params.go b/vehicle/audi/params.go deleted file mode 100644 index 9484322bc..000000000 --- a/vehicle/audi/params.go +++ /dev/null @@ -1,20 +0,0 @@ -package audi - -import "net/url" - -// Authorization parameters -var AuthParams = url.Values{ - "response_type": {"code"}, - "client_id": {"f4d0934f-32bf-4ce4-b3c4-699a7049ad26@apps_vw-dilab_com"}, - "redirect_uri": {"myaudi:///"}, - "scope": {"openid profile mbb"}, // vin badge birthdate nickname email address phone name picture - "prompt": {"login"}, - "ui_locales": {"de-DE"}, -} - -var IDKParams = url.Values{ - "client_id": {"f4d0934f-32bf-4ce4-b3c4-699a7049ad26@apps_vw-dilab_com"}, - "redirect_uri": {"myaudi:///"}, -} - -const AZSConfig = "myaudi" diff --git a/vehicle/audi/samples/status.json b/vehicle/audi/samples/status.json deleted file mode 100644 index cd9157d13..000000000 --- a/vehicle/audi/samples/status.json +++ /dev/null @@ -1,1445 +0,0 @@ -{ - "StoredVehicleDataResponse": { - "vin": "", - "vehicleData": { - "data": [ - { - "id": "0x0101010001", - "field": [ - { - "id": "0x0101010001", - "tsCarSentUtc": "2021-09-05T07:54:20Z", - "tsCarSent": "2021-09-05T07:54:19", - "tsCarCaptured": "2021-09-05T07:54:19", - "tsTssReceivedUtc": "2021-09-05T07:54:23Z", - "milCarCaptured": 25009, - "milCarSent": 25009, - "value": "echo" - } - ] - }, - { - "id": "0x0101010002", - "field": [ - { - "id": "0x0101010002", - "tsCarSentUtc": "2021-09-05T07:54:20Z", - "tsCarSent": "2021-09-05T07:54:19", - "tsCarCaptured": "2021-09-05T07:54:19", - "tsTssReceivedUtc": "2021-09-05T07:54:23Z", - "milCarCaptured": 25009, - "milCarSent": 25009, - "value": "25009" - } - ] - }, - { - "id": "0x0203FFFFFF", - "field": [ - { - "id": "0x0203010001", - "tsCarSentUtc": "2021-09-05T07:54:20Z", - "tsCarSent": "2021-09-05T07:54:19", - "tsCarCaptured": "2021-09-05T09:52:12", - "tsTssReceivedUtc": "2021-09-05T07:54:23Z", - "milCarCaptured": 25009, - "milCarSent": 25009, - "value": "-2700", - "unit": "km" - }, - { - "id": "0x0203010002", - "tsCarSentUtc": "2021-09-05T07:54:20Z", - "tsCarSent": "2021-09-05T07:54:19", - "tsCarCaptured": "2021-09-05T09:52:12", - "tsTssReceivedUtc": "2021-09-05T07:54:23Z", - "milCarCaptured": 25009, - "milCarSent": 25009, - "value": "-79", - "unit": "d" - }, - { - "id": "0x0203010003", - "tsCarSentUtc": "2021-09-05T07:54:20Z", - "tsCarSent": "2021-09-05T07:54:19", - "tsCarCaptured": "2021-09-05T09:52:12", - "tsTssReceivedUtc": "2021-09-05T07:54:23Z", - "milCarCaptured": 25009, - "milCarSent": 25009, - "value": "-5000", - "unit": "km" - }, - { - "id": "0x0203010004", - "tsCarSentUtc": "2021-09-05T07:54:20Z", - "tsCarSent": "2021-09-05T07:54:19", - "tsCarCaptured": "2021-09-05T09:52:12", - "tsTssReceivedUtc": "2021-09-05T07:54:23Z", - "milCarCaptured": 25009, - "milCarSent": 25009, - "value": "-79", - "unit": "d" - }, - { - "id": "0x0203010005", - "tsCarSentUtc": "2021-09-05T07:54:20Z", - "tsCarSent": "2021-09-05T07:54:19", - "tsCarCaptured": "2021-09-05T09:52:12", - "tsTssReceivedUtc": "2021-09-05T07:54:23Z", - "milCarCaptured": 25009, - "milCarSent": 25009, - "value": "0", - "textId": "interval.inspection.warn" - }, - { - "id": "0x0203010006", - "tsCarSentUtc": "2021-09-05T07:54:20Z", - "tsCarSent": "2021-09-05T07:54:19", - "tsCarCaptured": "2021-09-05T09:52:12", - "tsTssReceivedUtc": "2021-09-05T07:54:23Z", - "milCarCaptured": 25009, - "milCarSent": 25009, - "value": "0", - "textId": "interval.inspection.warn" - }, - { - "id": "0x0203010007", - "tsCarSentUtc": "2021-09-05T07:54:20Z", - "tsCarSent": "2021-09-05T07:54:19", - "tsCarCaptured": "2021-09-05T09:52:12", - "tsTssReceivedUtc": "2021-09-05T07:54:23Z", - "milCarCaptured": 25009, - "milCarSent": 25009, - "value": "43", - "unit": "km" - } - ] - }, - { - "id": "0x0204040001", - "field": [ - { - "id": "0x0204040001", - "tsCarSentUtc": "2021-09-05T07:54:20Z", - "tsCarSent": "2021-09-05T07:54:19", - "tsCarCaptured": "2021-09-05T09:52:12", - "tsTssReceivedUtc": "2021-09-05T07:54:23Z", - "milCarCaptured": 25009, - "milCarSent": 25009, - "value": "1.0", - "unit": "l" - } - ] - }, - { - "id": "0x0204040002", - "field": [ - { - "id": "0x0204040002", - "tsCarSentUtc": "2021-09-05T07:54:20Z", - "tsCarSent": "2021-09-05T07:54:19", - "tsCarCaptured": "2021-09-05T09:52:12", - "tsTssReceivedUtc": "2021-09-05T07:54:23Z", - "milCarCaptured": 25009, - "milCarSent": 25009, - "value": "0", - "textId": "oil.min.ok" - } - ] - }, - { - "id": "0x0204040003", - "field": [ - { - "id": "0x0204040003", - "tsCarSentUtc": "2021-09-05T07:54:20Z", - "tsCarSent": "2021-09-05T07:54:19", - "tsCarCaptured": "2021-09-05T09:52:12", - "tsTssReceivedUtc": "2021-09-05T07:54:23Z", - "milCarCaptured": 25009, - "milCarSent": 25009, - "value": "100.0", - "unit": "%", - "textId": "oil.level" - } - ] - }, - { - "id": "0x0204040004", - "field": [ - { - "id": "0x0204040004", - "tsCarSentUtc": "2021-09-05T07:54:20Z", - "tsCarSent": "2021-09-05T07:54:19", - "tsCarCaptured": "2021-09-05T09:52:12", - "tsTssReceivedUtc": "2021-09-05T07:54:23Z", - "milCarCaptured": 25009, - "milCarSent": 25009, - "value": "1", - "textId": "oilDisplay.1" - } - ] - }, - { - "id": "0x02040C0001", - "field": [ - { - "id": "0x02040C0001", - "tsCarSentUtc": "2021-09-05T07:54:20Z", - "tsCarSent": "2021-09-05T07:54:19", - "tsCarCaptured": "2021-09-05T09:52:12", - "tsTssReceivedUtc": "2021-09-05T07:54:23Z", - "milCarCaptured": 25009, - "milCarSent": 25009, - "textId": "not_supported" - } - ] - }, - { - "id": "0x02040C0002", - "field": [ - { - "id": "0x02040C0002", - "tsCarSentUtc": "2021-09-05T07:54:20Z", - "tsCarSent": "2021-09-05T07:54:19", - "tsCarCaptured": "2021-09-05T09:52:12", - "tsTssReceivedUtc": "2021-09-05T07:54:23Z", - "milCarCaptured": 25009, - "milCarSent": 25009, - "textId": "scr.no_driveability" - } - ] - }, - { - "id": "0x030101FFFF", - "field": [ - { - "id": "0x0301010001", - "tsCarSentUtc": "2021-09-05T07:54:20Z", - "tsCarSent": "2021-09-05T07:54:19", - "tsCarCaptured": "2021-09-05T07:54:19", - "tsTssReceivedUtc": "2021-09-05T07:54:23Z", - "milCarCaptured": 25009, - "milCarSent": 25009, - "value": "2", - "textId": "status_parking_light_off" - } - ] - }, - { - "id": "0x030102FFFF", - "field": [ - { - "id": "0x0301020001", - "tsCarSentUtc": "2021-09-05T07:54:20Z", - "tsCarSent": "2021-09-05T07:54:19", - "tsCarCaptured": "2021-09-05T07:54:19", - "tsTssReceivedUtc": "2021-09-05T07:54:23Z", - "milCarCaptured": 25009, - "milCarSent": 25009, - "value": "2866", - "unit": "dK", - "textId": "temperature_outside_valid" - } - ] - }, - { - "id": "0x030103FFFF", - "field": [ - { - "id": "0x0301030001", - "tsCarSentUtc": "2021-09-05T07:54:20Z", - "tsCarSent": "2021-09-05T07:54:19", - "tsCarCaptured": "2021-09-05T07:54:19", - "tsTssReceivedUtc": "2021-09-05T07:54:23Z", - "milCarCaptured": 25009, - "milCarSent": 25009, - "value": "1", - "textId": "parking_brake_active" - }, - { - "id": "0x0301030002", - "tsCarSentUtc": "2021-09-05T07:54:20Z", - "tsCarSent": "2021-09-05T07:54:19", - "tsCarCaptured": "2021-09-05T07:54:19", - "tsTssReceivedUtc": "2021-09-05T07:54:23Z", - "milCarCaptured": 25009, - "milCarSent": 25009, - "value": "1", - "unit": "%", - "textId": "soc_ok" - }, - { - "id": "0x0301030003", - "tsCarSentUtc": "2021-09-05T07:54:20Z", - "tsCarSent": "2021-09-05T07:54:19", - "tsCarCaptured": "2021-09-05T07:54:19", - "tsTssReceivedUtc": "2021-09-05T07:54:23Z", - "milCarCaptured": 25009, - "milCarSent": 25009, - "value": "0", - "unit": "%", - "textId": "bem_ok" - }, - { - "id": "0x0301030004", - "tsCarSentUtc": "2021-09-05T07:54:20Z", - "tsCarSent": "2021-09-05T07:54:19", - "tsCarCaptured": "2021-09-05T07:54:19", - "tsTssReceivedUtc": "2021-09-05T07:54:23Z", - "milCarCaptured": 25009, - "milCarSent": 25009, - "value": "0", - "unit": "km/h", - "textId": "speed_ok" - }, - { - "id": "0x0301030005", - "tsCarSentUtc": "2021-09-05T07:54:20Z", - "tsCarSent": "2021-09-05T07:54:19", - "tsCarCaptured": "2021-09-05T07:54:19", - "tsTssReceivedUtc": "2021-09-05T07:54:23Z", - "milCarCaptured": 25009, - "milCarSent": 25009, - "value": "460", - "unit": "km", - "textId": "range_ok" - }, - { - "id": "0x0301030006", - "tsCarSentUtc": "2021-09-05T07:54:20Z", - "tsCarSent": "2021-09-05T07:54:19", - "tsCarCaptured": "2021-09-05T07:54:19", - "tsTssReceivedUtc": "2021-09-05T07:54:23Z", - "milCarCaptured": 25009, - "milCarSent": 25009, - "value": "460", - "unit": "km", - "textId": "range_ok" - }, - { - "id": "0x0301030007", - "tsCarSentUtc": "2021-09-05T07:54:20Z", - "tsCarSent": "2021-09-05T07:54:19", - "tsCarCaptured": "2021-09-05T07:54:19", - "tsTssReceivedUtc": "2021-09-05T07:54:23Z", - "milCarCaptured": 25009, - "milCarSent": 25009, - "value": "6", - "textId": "engine_type_gasoline" - }, - { - "id": "0x0301030008", - "tsCarSentUtc": "2021-09-05T07:54:20Z", - "tsCarSent": "2021-09-05T07:54:19", - "tsCarCaptured": "2021-09-05T07:54:19", - "tsTssReceivedUtc": "2021-09-05T07:54:23Z", - "milCarCaptured": 25009, - "milCarSent": 25009, - "value": "0", - "unit": "km", - "textId": "range_ok" - }, - { - "id": "0x0301030009", - "tsCarSentUtc": "2021-09-05T07:54:20Z", - "tsCarSent": "2021-09-05T07:54:19", - "tsCarCaptured": "2021-09-05T07:54:19", - "tsTssReceivedUtc": "2021-09-05T07:54:23Z", - "milCarCaptured": 25009, - "milCarSent": 25009, - "value": "3", - "textId": "engine_type_electric" - }, - { - "id": "0x030103000A", - "tsCarSentUtc": "2021-09-05T07:54:20Z", - "tsCarSent": "2021-09-05T07:54:19", - "tsCarCaptured": "2021-09-05T07:54:19", - "tsTssReceivedUtc": "2021-09-05T07:54:23Z", - "milCarCaptured": 25009, - "milCarSent": 25009, - "value": "82", - "unit": "%", - "textId": "fuel_level_ok" - }, - { - "id": "0x030103000B", - "tsCarSentUtc": "2021-09-05T07:54:20Z", - "tsCarSent": "2021-09-05T07:54:19", - "tsCarCaptured": "2021-09-05T07:54:19", - "tsTssReceivedUtc": "2021-09-05T07:54:23Z", - "milCarCaptured": 25009, - "milCarSent": 25009, - "value": "0", - "textId": "fuel_level_measured" - }, - { - "id": "0x030103000D", - "tsCarSentUtc": "2021-09-05T07:54:20Z", - "tsCarSent": "2021-09-05T07:54:19", - "tsCarCaptured": "2021-09-05T07:54:19", - "tsTssReceivedUtc": "2021-09-05T07:54:23Z", - "milCarCaptured": 25009, - "milCarSent": 25009, - "textId": "gas_level_error" - } - ] - }, - { - "id": "0x030104FFFF", - "field": [ - { - "id": "0x0301040001", - "tsCarSentUtc": "2021-09-05T07:54:20Z", - "tsCarSent": "2021-09-05T07:54:19", - "tsCarCaptured": "2021-09-05T07:54:19", - "tsTssReceivedUtc": "2021-09-05T07:54:23Z", - "milCarCaptured": 25009, - "milCarSent": 25009, - "value": "2", - "textId": "door_locked" - }, - { - "id": "0x0301040002", - "tsCarSentUtc": "2021-09-05T07:54:20Z", - "tsCarSent": "2021-09-05T07:54:19", - "tsCarCaptured": "2021-09-05T07:54:19", - "tsTssReceivedUtc": "2021-09-05T07:54:23Z", - "milCarCaptured": 25009, - "milCarSent": 25009, - "value": "3", - "textId": "door_closed" - }, - { - "id": "0x0301040003", - "tsCarSentUtc": "2021-09-05T07:54:20Z", - "tsCarSent": "2021-09-05T07:54:19", - "tsCarCaptured": "2021-09-05T07:54:19", - "tsTssReceivedUtc": "2021-09-05T07:54:23Z", - "milCarCaptured": 25009, - "milCarSent": 25009, - "value": "3", - "textId": "door_unsafe" - }, - { - "id": "0x0301040004", - "tsCarSentUtc": "2021-09-05T07:54:20Z", - "tsCarSent": "2021-09-05T07:54:19", - "tsCarCaptured": "2021-09-05T07:54:19", - "tsTssReceivedUtc": "2021-09-05T07:54:23Z", - "milCarCaptured": 25009, - "milCarSent": 25009, - "value": "2", - "textId": "door_locked" - }, - { - "id": "0x0301040005", - "tsCarSentUtc": "2021-09-05T07:54:20Z", - "tsCarSent": "2021-09-05T07:54:19", - "tsCarCaptured": "2021-09-05T07:54:19", - "tsTssReceivedUtc": "2021-09-05T07:54:23Z", - "milCarCaptured": 25009, - "milCarSent": 25009, - "value": "3", - "textId": "door_closed" - }, - { - "id": "0x0301040006", - "tsCarSentUtc": "2021-09-05T07:54:20Z", - "tsCarSent": "2021-09-05T07:54:19", - "tsCarCaptured": "2021-09-05T07:54:19", - "tsTssReceivedUtc": "2021-09-05T07:54:23Z", - "milCarCaptured": 25009, - "milCarSent": 25009, - "value": "3", - "textId": "door_unsafe" - }, - { - "id": "0x0301040007", - "tsCarSentUtc": "2021-09-05T07:54:20Z", - "tsCarSent": "2021-09-05T07:54:19", - "tsCarCaptured": "2021-09-05T07:54:19", - "tsTssReceivedUtc": "2021-09-05T07:54:23Z", - "milCarCaptured": 25009, - "milCarSent": 25009, - "value": "2", - "textId": "door_locked" - }, - { - "id": "0x0301040008", - "tsCarSentUtc": "2021-09-05T07:54:20Z", - "tsCarSent": "2021-09-05T07:54:19", - "tsCarCaptured": "2021-09-05T07:54:19", - "tsTssReceivedUtc": "2021-09-05T07:54:23Z", - "milCarCaptured": 25009, - "milCarSent": 25009, - "value": "3", - "textId": "door_closed" - }, - { - "id": "0x0301040009", - "tsCarSentUtc": "2021-09-05T07:54:20Z", - "tsCarSent": "2021-09-05T07:54:19", - "tsCarCaptured": "2021-09-05T07:54:19", - "tsTssReceivedUtc": "2021-09-05T07:54:23Z", - "milCarCaptured": 25009, - "milCarSent": 25009, - "value": "3", - "textId": "door_unsafe" - }, - { - "id": "0x030104000A", - "tsCarSentUtc": "2021-09-05T07:54:20Z", - "tsCarSent": "2021-09-05T07:54:19", - "tsCarCaptured": "2021-09-05T07:54:19", - "tsTssReceivedUtc": "2021-09-05T07:54:23Z", - "milCarCaptured": 25009, - "milCarSent": 25009, - "value": "2", - "textId": "door_locked" - }, - { - "id": "0x030104000B", - "tsCarSentUtc": "2021-09-05T07:54:20Z", - "tsCarSent": "2021-09-05T07:54:19", - "tsCarCaptured": "2021-09-05T07:54:19", - "tsTssReceivedUtc": "2021-09-05T07:54:23Z", - "milCarCaptured": 25009, - "milCarSent": 25009, - "value": "3", - "textId": "door_closed" - }, - { - "id": "0x030104000C", - "tsCarSentUtc": "2021-09-05T07:54:20Z", - "tsCarSent": "2021-09-05T07:54:19", - "tsCarCaptured": "2021-09-05T07:54:19", - "tsTssReceivedUtc": "2021-09-05T07:54:23Z", - "milCarCaptured": 25009, - "milCarSent": 25009, - "value": "3", - "textId": "door_unsafe" - }, - { - "id": "0x030104000D", - "tsCarSentUtc": "2021-09-05T07:54:20Z", - "tsCarSent": "2021-09-05T07:54:19", - "tsCarCaptured": "2021-09-05T07:54:19", - "tsTssReceivedUtc": "2021-09-05T07:54:23Z", - "milCarCaptured": 25009, - "milCarSent": 25009, - "value": "2", - "textId": "door_locked" - }, - { - "id": "0x030104000E", - "tsCarSentUtc": "2021-09-05T07:54:20Z", - "tsCarSent": "2021-09-05T07:54:19", - "tsCarCaptured": "2021-09-05T07:54:19", - "tsTssReceivedUtc": "2021-09-05T07:54:23Z", - "milCarCaptured": 25009, - "milCarSent": 25009, - "value": "3", - "textId": "door_closed" - }, - { - "id": "0x030104000F", - "tsCarSentUtc": "2021-09-05T07:54:20Z", - "tsCarSent": "2021-09-05T07:54:19", - "tsCarCaptured": "2021-09-05T07:54:19", - "tsTssReceivedUtc": "2021-09-05T07:54:23Z", - "milCarCaptured": 25009, - "milCarSent": 25009, - "value": "3", - "textId": "door_unsafe" - }, - { - "id": "0x0301040010", - "tsCarSentUtc": "2021-09-05T07:54:20Z", - "tsCarSent": "2021-09-05T07:54:19", - "tsCarCaptured": "2021-09-05T07:54:19", - "tsTssReceivedUtc": "2021-09-05T07:54:23Z", - "milCarCaptured": 25009, - "milCarSent": 25009, - "value": "3", - "textId": "door_unlocked" - }, - { - "id": "0x0301040011", - "tsCarSentUtc": "2021-09-05T07:54:20Z", - "tsCarSent": "2021-09-05T07:54:19", - "tsCarCaptured": "2021-09-05T07:54:19", - "tsTssReceivedUtc": "2021-09-05T07:54:23Z", - "milCarCaptured": 25009, - "milCarSent": 25009, - "value": "3", - "textId": "door_closed" - }, - { - "id": "0x0301040012", - "tsCarSentUtc": "2021-09-05T07:54:20Z", - "tsCarSent": "2021-09-05T07:54:19", - "tsCarCaptured": "2021-09-05T07:54:19", - "tsTssReceivedUtc": "2021-09-05T07:54:23Z", - "milCarCaptured": 25009, - "milCarSent": 25009, - "value": "3", - "textId": "door_unsafe" - } - ] - }, - { - "id": "0x030105FFFF", - "field": [ - { - "id": "0x0301050001", - "tsCarSentUtc": "2021-09-05T07:54:20Z", - "tsCarSent": "2021-09-05T07:54:19", - "tsCarCaptured": "2021-09-05T07:54:19", - "tsTssReceivedUtc": "2021-09-05T07:54:23Z", - "milCarCaptured": 25009, - "milCarSent": 25009, - "value": "3", - "textId": "window_closed" - }, - { - "id": "0x0301050002", - "tsCarSentUtc": "2021-09-05T07:54:20Z", - "tsCarSent": "2021-09-05T07:54:19", - "tsCarCaptured": "2021-09-05T07:54:19", - "tsTssReceivedUtc": "2021-09-05T07:54:23Z", - "milCarCaptured": 25009, - "milCarSent": 25009, - "value": "0", - "unit": "%" - }, - { - "id": "0x0301050003", - "tsCarSentUtc": "2021-09-05T07:54:20Z", - "tsCarSent": "2021-09-05T07:54:19", - "tsCarCaptured": "2021-09-05T07:54:19", - "tsTssReceivedUtc": "2021-09-05T07:54:23Z", - "milCarCaptured": 25009, - "milCarSent": 25009, - "value": "3", - "textId": "window_closed" - }, - { - "id": "0x0301050004", - "tsCarSentUtc": "2021-09-05T07:54:20Z", - "tsCarSent": "2021-09-05T07:54:19", - "tsCarCaptured": "2021-09-05T07:54:19", - "tsTssReceivedUtc": "2021-09-05T07:54:23Z", - "milCarCaptured": 25009, - "milCarSent": 25009, - "value": "0", - "unit": "%" - }, - { - "id": "0x0301050005", - "tsCarSentUtc": "2021-09-05T07:54:20Z", - "tsCarSent": "2021-09-05T07:54:19", - "tsCarCaptured": "2021-09-05T07:54:19", - "tsTssReceivedUtc": "2021-09-05T07:54:23Z", - "milCarCaptured": 25009, - "milCarSent": 25009, - "value": "3", - "textId": "window_closed" - }, - { - "id": "0x0301050006", - "tsCarSentUtc": "2021-09-05T07:54:20Z", - "tsCarSent": "2021-09-05T07:54:19", - "tsCarCaptured": "2021-09-05T07:54:19", - "tsTssReceivedUtc": "2021-09-05T07:54:23Z", - "milCarCaptured": 25009, - "milCarSent": 25009, - "value": "0", - "unit": "%" - }, - { - "id": "0x0301050007", - "tsCarSentUtc": "2021-09-05T07:54:20Z", - "tsCarSent": "2021-09-05T07:54:19", - "tsCarCaptured": "2021-09-05T07:54:19", - "tsTssReceivedUtc": "2021-09-05T07:54:23Z", - "milCarCaptured": 25009, - "milCarSent": 25009, - "value": "3", - "textId": "window_closed" - }, - { - "id": "0x0301050008", - "tsCarSentUtc": "2021-09-05T07:54:20Z", - "tsCarSent": "2021-09-05T07:54:19", - "tsCarCaptured": "2021-09-05T07:54:19", - "tsTssReceivedUtc": "2021-09-05T07:54:23Z", - "milCarCaptured": 25009, - "milCarSent": 25009, - "value": "0", - "unit": "%" - }, - { - "id": "0x0301050009", - "tsCarSentUtc": "2021-09-05T07:54:20Z", - "tsCarSent": "2021-09-05T07:54:19", - "tsCarCaptured": "2021-09-05T07:54:19", - "tsTssReceivedUtc": "2021-09-05T07:54:23Z", - "milCarCaptured": 25009, - "milCarSent": 25009, - "value": "0", - "textId": "window_unsupported" - }, - { - "id": "0x030105000B", - "tsCarSentUtc": "2021-09-05T07:54:20Z", - "tsCarSent": "2021-09-05T07:54:19", - "tsCarCaptured": "2021-09-05T07:54:19", - "tsTssReceivedUtc": "2021-09-05T07:54:23Z", - "milCarCaptured": 25009, - "milCarSent": 25009, - "value": "0", - "textId": "window_unsupported" - }, - { - "id": "0x030105000D", - "tsCarSentUtc": "2021-09-05T07:54:20Z", - "tsCarSent": "2021-09-05T07:54:19", - "tsCarCaptured": "2021-09-05T07:54:19", - "tsTssReceivedUtc": "2021-09-05T07:54:23Z", - "milCarCaptured": 25009, - "milCarSent": 25009, - "value": "0", - "textId": "window_unsupported" - }, - { - "id": "0x030105000F", - "tsCarSentUtc": "2021-09-05T07:54:20Z", - "tsCarSent": "2021-09-05T07:54:19", - "tsCarCaptured": "2021-09-05T07:54:19", - "tsTssReceivedUtc": "2021-09-05T07:54:23Z", - "milCarCaptured": 25009, - "milCarSent": 25009, - "value": "0", - "textId": "window_unsupported" - }, - { - "id": "0x0301050011", - "tsCarSentUtc": "2021-09-05T07:54:20Z", - "tsCarSent": "2021-09-05T07:54:19", - "tsCarCaptured": "2021-09-05T07:54:19", - "tsTssReceivedUtc": "2021-09-05T07:54:23Z", - "milCarCaptured": 25009, - "milCarSent": 25009, - "value": "1", - "textId": "window_invalid" - } - ] - }, - { - "id": "0x0301060001", - "field": [ - { - "id": "0x0301060001", - "tsCarSentUtc": "2021-09-05T07:54:20Z", - "tsCarSent": "2021-09-05T07:54:19", - "tsCarCaptured": "2021-09-05T07:54:19", - "tsTssReceivedUtc": "2021-09-05T07:54:23Z", - "milCarCaptured": 25009, - "milCarSent": 25009, - "value": "1", - "textId": "tyre_invalid" - }, - { - "id": "0x0301060001", - "tsCarSentUtc": "2021-09-05T07:54:20Z", - "tsCarSent": "2021-09-05T07:54:19", - "tsCarCaptured": "2021-09-05T07:54:19", - "tsTssReceivedUtc": "2021-09-05T07:54:23Z", - "milCarCaptured": 25009, - "milCarSent": 25009, - "value": "1", - "textId": "tyre_invalid" - } - ] - }, - { - "id": "0x0301060002", - "field": [ - { - "id": "0x0301060002", - "tsCarSentUtc": "2021-09-05T07:54:20Z", - "tsCarSent": "2021-09-05T07:54:19", - "tsCarCaptured": "2021-09-05T07:54:19", - "tsTssReceivedUtc": "2021-09-05T07:54:23Z", - "milCarCaptured": 25009, - "milCarSent": 25009, - "value": "1", - "textId": "tyre_invalid" - }, - { - "id": "0x0301060002", - "tsCarSentUtc": "2021-09-05T07:54:20Z", - "tsCarSent": "2021-09-05T07:54:19", - "tsCarCaptured": "2021-09-05T07:54:19", - "tsTssReceivedUtc": "2021-09-05T07:54:23Z", - "milCarCaptured": 25009, - "milCarSent": 25009, - "value": "1", - "textId": "tyre_invalid" - } - ] - }, - { - "id": "0x0301060003", - "field": [ - { - "id": "0x0301060003", - "tsCarSentUtc": "2021-09-05T07:54:20Z", - "tsCarSent": "2021-09-05T07:54:19", - "tsCarCaptured": "2021-09-05T07:54:19", - "tsTssReceivedUtc": "2021-09-05T07:54:23Z", - "milCarCaptured": 25009, - "milCarSent": 25009, - "value": "1", - "textId": "tyre_invalid" - }, - { - "id": "0x0301060003", - "tsCarSentUtc": "2021-09-05T07:54:20Z", - "tsCarSent": "2021-09-05T07:54:19", - "tsCarCaptured": "2021-09-05T07:54:19", - "tsTssReceivedUtc": "2021-09-05T07:54:23Z", - "milCarCaptured": 25009, - "milCarSent": 25009, - "value": "1", - "textId": "tyre_invalid" - } - ] - }, - { - "id": "0x0301060004", - "field": [ - { - "id": "0x0301060004", - "tsCarSentUtc": "2021-09-05T07:54:20Z", - "tsCarSent": "2021-09-05T07:54:19", - "tsCarCaptured": "2021-09-05T07:54:19", - "tsTssReceivedUtc": "2021-09-05T07:54:23Z", - "milCarCaptured": 25009, - "milCarSent": 25009, - "value": "1", - "textId": "tyre_invalid" - }, - { - "id": "0x0301060004", - "tsCarSentUtc": "2021-09-05T07:54:20Z", - "tsCarSent": "2021-09-05T07:54:19", - "tsCarCaptured": "2021-09-05T07:54:19", - "tsTssReceivedUtc": "2021-09-05T07:54:23Z", - "milCarCaptured": 25009, - "milCarSent": 25009, - "value": "1", - "textId": "tyre_invalid" - } - ] - }, - { - "id": "0x0301060005", - "field": [ - { - "id": "0x0301060005", - "tsCarSentUtc": "2021-09-05T07:54:20Z", - "tsCarSent": "2021-09-05T07:54:19", - "tsCarCaptured": "2021-09-05T07:54:19", - "tsTssReceivedUtc": "2021-09-05T07:54:23Z", - "milCarCaptured": 25009, - "milCarSent": 25009, - "value": "1", - "textId": "tyre_invalid" - }, - { - "id": "0x0301060005", - "tsCarSentUtc": "2021-09-05T07:54:20Z", - "tsCarSent": "2021-09-05T07:54:19", - "tsCarCaptured": "2021-09-05T07:54:19", - "tsTssReceivedUtc": "2021-09-05T07:54:23Z", - "milCarCaptured": 25009, - "milCarSent": 25009, - "value": "1", - "textId": "tyre_invalid" - } - ] - }, - { - "id": "0x0301060006", - "field": [ - { - "id": "0x0301060006", - "tsCarSentUtc": "2021-09-05T07:54:20Z", - "tsCarSent": "2021-09-05T07:54:19", - "tsCarCaptured": "2021-09-05T07:54:19", - "tsTssReceivedUtc": "2021-09-05T07:54:23Z", - "milCarCaptured": 25009, - "milCarSent": 25009, - "value": "1", - "textId": "tyre_invalid" - }, - { - "id": "0x0301060006", - "tsCarSentUtc": "2021-09-05T07:54:20Z", - "tsCarSent": "2021-09-05T07:54:19", - "tsCarCaptured": "2021-09-05T07:54:19", - "tsTssReceivedUtc": "2021-09-05T07:54:23Z", - "milCarCaptured": 25009, - "milCarSent": 25009, - "value": "1", - "textId": "tyre_invalid" - } - ] - }, - { - "id": "0x0301060007", - "field": [ - { - "id": "0x0301060007", - "tsCarSentUtc": "2021-09-05T07:54:20Z", - "tsCarSent": "2021-09-05T07:54:19", - "tsCarCaptured": "2021-09-05T07:54:19", - "tsTssReceivedUtc": "2021-09-05T07:54:23Z", - "milCarCaptured": 25009, - "milCarSent": 25009, - "value": "1", - "textId": "tyre_invalid" - }, - { - "id": "0x0301060007", - "tsCarSentUtc": "2021-09-05T07:54:20Z", - "tsCarSent": "2021-09-05T07:54:19", - "tsCarCaptured": "2021-09-05T07:54:19", - "tsTssReceivedUtc": "2021-09-05T07:54:23Z", - "milCarCaptured": 25009, - "milCarSent": 25009, - "value": "1", - "textId": "tyre_invalid" - } - ] - }, - { - "id": "0x0301060008", - "field": [ - { - "id": "0x0301060008", - "tsCarSentUtc": "2021-09-05T07:54:20Z", - "tsCarSent": "2021-09-05T07:54:19", - "tsCarCaptured": "2021-09-05T07:54:19", - "tsTssReceivedUtc": "2021-09-05T07:54:23Z", - "milCarCaptured": 25009, - "milCarSent": 25009, - "value": "1", - "textId": "tyre_invalid" - }, - { - "id": "0x0301060008", - "tsCarSentUtc": "2021-09-05T07:54:20Z", - "tsCarSent": "2021-09-05T07:54:19", - "tsCarCaptured": "2021-09-05T07:54:19", - "tsTssReceivedUtc": "2021-09-05T07:54:23Z", - "milCarCaptured": 25009, - "milCarSent": 25009, - "value": "1", - "textId": "tyre_invalid" - } - ] - }, - { - "id": "0x0301060009", - "field": [ - { - "id": "0x0301060009", - "tsCarSentUtc": "2021-09-05T07:54:20Z", - "tsCarSent": "2021-09-05T07:54:19", - "tsCarCaptured": "2021-09-05T07:54:19", - "tsTssReceivedUtc": "2021-09-05T07:54:23Z", - "milCarCaptured": 25009, - "milCarSent": 25009, - "value": "1", - "textId": "tyre_invalid" - }, - { - "id": "0x0301060009", - "tsCarSentUtc": "2021-09-05T07:54:20Z", - "tsCarSent": "2021-09-05T07:54:19", - "tsCarCaptured": "2021-09-05T07:54:19", - "tsTssReceivedUtc": "2021-09-05T07:54:23Z", - "milCarCaptured": 25009, - "milCarSent": 25009, - "value": "1", - "textId": "tyre_invalid" - } - ] - }, - { - "id": "0x030106000A", - "field": [ - { - "id": "0x030106000A", - "tsCarSentUtc": "2021-09-05T07:54:20Z", - "tsCarSent": "2021-09-05T07:54:19", - "tsCarCaptured": "2021-09-05T07:54:19", - "tsTssReceivedUtc": "2021-09-05T07:54:23Z", - "milCarCaptured": 25009, - "milCarSent": 25009, - "value": "1", - "textId": "tyre_invalid" - }, - { - "id": "0x030106000A", - "tsCarSentUtc": "2021-09-05T07:54:20Z", - "tsCarSent": "2021-09-05T07:54:19", - "tsCarCaptured": "2021-09-05T07:54:19", - "tsTssReceivedUtc": "2021-09-05T07:54:23Z", - "milCarCaptured": 25009, - "milCarSent": 25009, - "value": "1", - "textId": "tyre_invalid" - } - ] - }, - { - "id": "0x030106000B", - "field": [ - { - "id": "0x030106000B", - "tsCarSentUtc": "2021-09-05T07:54:20Z", - "tsCarSent": "2021-09-05T07:54:19", - "tsCarCaptured": "2021-09-05T07:54:19", - "tsTssReceivedUtc": "2021-09-05T07:54:23Z", - "milCarCaptured": 25009, - "milCarSent": 25009, - "value": "1", - "textId": "tyre_invalid" - }, - { - "id": "0x030106000B", - "tsCarSentUtc": "2021-09-05T07:54:20Z", - "tsCarSent": "2021-09-05T07:54:19", - "tsCarCaptured": "2021-09-05T07:54:19", - "tsTssReceivedUtc": "2021-09-05T07:54:23Z", - "milCarCaptured": 25009, - "milCarSent": 25009, - "value": "1", - "textId": "tyre_invalid" - } - ] - }, - { - "id": "0x030106000C", - "field": [ - { - "id": "0x030106000C", - "tsCarSentUtc": "2021-09-05T07:54:20Z", - "tsCarSent": "2021-09-05T07:54:19", - "tsCarCaptured": "2021-09-05T07:54:19", - "tsTssReceivedUtc": "2021-09-05T07:54:23Z", - "milCarCaptured": 25009, - "milCarSent": 25009, - "value": "1", - "textId": "tyre_invalid" - }, - { - "id": "0x030106000C", - "tsCarSentUtc": "2021-09-05T07:54:20Z", - "tsCarSent": "2021-09-05T07:54:19", - "tsCarCaptured": "2021-09-05T07:54:19", - "tsTssReceivedUtc": "2021-09-05T07:54:23Z", - "milCarCaptured": 25009, - "milCarSent": 25009, - "value": "1", - "textId": "tyre_invalid" - } - ] - }, - { - "id": "0x030106000D", - "field": [ - { - "id": "0x030106000D", - "tsCarSentUtc": "2021-09-05T07:54:20Z", - "tsCarSent": "2021-09-05T07:54:19", - "tsCarCaptured": "2021-09-05T07:54:19", - "tsTssReceivedUtc": "2021-09-05T07:54:23Z", - "milCarCaptured": 25009, - "milCarSent": 25009, - "value": "1", - "textId": "tyre_invalid" - }, - { - "id": "0x030106000D", - "tsCarSentUtc": "2021-09-05T07:54:20Z", - "tsCarSent": "2021-09-05T07:54:19", - "tsCarCaptured": "2021-09-05T07:54:19", - "tsTssReceivedUtc": "2021-09-05T07:54:23Z", - "milCarCaptured": 25009, - "milCarSent": 25009, - "value": "1", - "textId": "tyre_invalid" - } - ] - }, - { - "id": "0x030106000E", - "field": [ - { - "id": "0x030106000E", - "tsCarSentUtc": "2021-09-05T07:54:20Z", - "tsCarSent": "2021-09-05T07:54:19", - "tsCarCaptured": "2021-09-05T07:54:19", - "tsTssReceivedUtc": "2021-09-05T07:54:23Z", - "milCarCaptured": 25009, - "milCarSent": 25009, - "value": "1", - "textId": "tyre_invalid" - }, - { - "id": "0x030106000E", - "tsCarSentUtc": "2021-09-05T07:54:20Z", - "tsCarSent": "2021-09-05T07:54:19", - "tsCarCaptured": "2021-09-05T07:54:19", - "tsTssReceivedUtc": "2021-09-05T07:54:23Z", - "milCarCaptured": 25009, - "milCarSent": 25009, - "value": "1", - "textId": "tyre_invalid" - } - ] - }, - { - "id": "0x030106000F", - "field": [ - { - "id": "0x0301060001", - "tsCarSentUtc": "2021-09-05T07:54:20Z", - "tsCarSent": "2021-09-05T07:54:19", - "tsCarCaptured": "2021-09-05T07:54:19", - "tsTssReceivedUtc": "2021-09-05T07:54:23Z", - "milCarCaptured": 25009, - "milCarSent": 25009, - "value": "1", - "textId": "tyre_invalid" - }, - { - "id": "0x0301060001", - "tsCarSentUtc": "2021-09-05T07:54:20Z", - "tsCarSent": "2021-09-05T07:54:19", - "tsCarCaptured": "2021-09-05T07:54:19", - "tsTssReceivedUtc": "2021-09-05T07:54:23Z", - "milCarCaptured": 25009, - "milCarSent": 25009, - "value": "1", - "textId": "tyre_invalid" - }, - { - "id": "0x0301060002", - "tsCarSentUtc": "2021-09-05T07:54:20Z", - "tsCarSent": "2021-09-05T07:54:19", - "tsCarCaptured": "2021-09-05T07:54:19", - "tsTssReceivedUtc": "2021-09-05T07:54:23Z", - "milCarCaptured": 25009, - "milCarSent": 25009, - "value": "1", - "textId": "tyre_invalid" - }, - { - "id": "0x0301060002", - "tsCarSentUtc": "2021-09-05T07:54:20Z", - "tsCarSent": "2021-09-05T07:54:19", - "tsCarCaptured": "2021-09-05T07:54:19", - "tsTssReceivedUtc": "2021-09-05T07:54:23Z", - "milCarCaptured": 25009, - "milCarSent": 25009, - "value": "1", - "textId": "tyre_invalid" - }, - { - "id": "0x0301060003", - "tsCarSentUtc": "2021-09-05T07:54:20Z", - "tsCarSent": "2021-09-05T07:54:19", - "tsCarCaptured": "2021-09-05T07:54:19", - "tsTssReceivedUtc": "2021-09-05T07:54:23Z", - "milCarCaptured": 25009, - "milCarSent": 25009, - "value": "1", - "textId": "tyre_invalid" - }, - { - "id": "0x0301060003", - "tsCarSentUtc": "2021-09-05T07:54:20Z", - "tsCarSent": "2021-09-05T07:54:19", - "tsCarCaptured": "2021-09-05T07:54:19", - "tsTssReceivedUtc": "2021-09-05T07:54:23Z", - "milCarCaptured": 25009, - "milCarSent": 25009, - "value": "1", - "textId": "tyre_invalid" - }, - { - "id": "0x0301060004", - "tsCarSentUtc": "2021-09-05T07:54:20Z", - "tsCarSent": "2021-09-05T07:54:19", - "tsCarCaptured": "2021-09-05T07:54:19", - "tsTssReceivedUtc": "2021-09-05T07:54:23Z", - "milCarCaptured": 25009, - "milCarSent": 25009, - "value": "1", - "textId": "tyre_invalid" - }, - { - "id": "0x0301060004", - "tsCarSentUtc": "2021-09-05T07:54:20Z", - "tsCarSent": "2021-09-05T07:54:19", - "tsCarCaptured": "2021-09-05T07:54:19", - "tsTssReceivedUtc": "2021-09-05T07:54:23Z", - "milCarCaptured": 25009, - "milCarSent": 25009, - "value": "1", - "textId": "tyre_invalid" - }, - { - "id": "0x0301060005", - "tsCarSentUtc": "2021-09-05T07:54:20Z", - "tsCarSent": "2021-09-05T07:54:19", - "tsCarCaptured": "2021-09-05T07:54:19", - "tsTssReceivedUtc": "2021-09-05T07:54:23Z", - "milCarCaptured": 25009, - "milCarSent": 25009, - "value": "1", - "textId": "tyre_invalid" - }, - { - "id": "0x0301060005", - "tsCarSentUtc": "2021-09-05T07:54:20Z", - "tsCarSent": "2021-09-05T07:54:19", - "tsCarCaptured": "2021-09-05T07:54:19", - "tsTssReceivedUtc": "2021-09-05T07:54:23Z", - "milCarCaptured": 25009, - "milCarSent": 25009, - "value": "1", - "textId": "tyre_invalid" - }, - { - "id": "0x0301060006", - "tsCarSentUtc": "2021-09-05T07:54:20Z", - "tsCarSent": "2021-09-05T07:54:19", - "tsCarCaptured": "2021-09-05T07:54:19", - "tsTssReceivedUtc": "2021-09-05T07:54:23Z", - "milCarCaptured": 25009, - "milCarSent": 25009, - "value": "1", - "textId": "tyre_invalid" - }, - { - "id": "0x0301060006", - "tsCarSentUtc": "2021-09-05T07:54:20Z", - "tsCarSent": "2021-09-05T07:54:19", - "tsCarCaptured": "2021-09-05T07:54:19", - "tsTssReceivedUtc": "2021-09-05T07:54:23Z", - "milCarCaptured": 25009, - "milCarSent": 25009, - "value": "1", - "textId": "tyre_invalid" - }, - { - "id": "0x0301060007", - "tsCarSentUtc": "2021-09-05T07:54:20Z", - "tsCarSent": "2021-09-05T07:54:19", - "tsCarCaptured": "2021-09-05T07:54:19", - "tsTssReceivedUtc": "2021-09-05T07:54:23Z", - "milCarCaptured": 25009, - "milCarSent": 25009, - "value": "1", - "textId": "tyre_invalid" - }, - { - "id": "0x0301060007", - "tsCarSentUtc": "2021-09-05T07:54:20Z", - "tsCarSent": "2021-09-05T07:54:19", - "tsCarCaptured": "2021-09-05T07:54:19", - "tsTssReceivedUtc": "2021-09-05T07:54:23Z", - "milCarCaptured": 25009, - "milCarSent": 25009, - "value": "1", - "textId": "tyre_invalid" - }, - { - "id": "0x0301060008", - "tsCarSentUtc": "2021-09-05T07:54:20Z", - "tsCarSent": "2021-09-05T07:54:19", - "tsCarCaptured": "2021-09-05T07:54:19", - "tsTssReceivedUtc": "2021-09-05T07:54:23Z", - "milCarCaptured": 25009, - "milCarSent": 25009, - "value": "1", - "textId": "tyre_invalid" - }, - { - "id": "0x0301060008", - "tsCarSentUtc": "2021-09-05T07:54:20Z", - "tsCarSent": "2021-09-05T07:54:19", - "tsCarCaptured": "2021-09-05T07:54:19", - "tsTssReceivedUtc": "2021-09-05T07:54:23Z", - "milCarCaptured": 25009, - "milCarSent": 25009, - "value": "1", - "textId": "tyre_invalid" - }, - { - "id": "0x0301060009", - "tsCarSentUtc": "2021-09-05T07:54:20Z", - "tsCarSent": "2021-09-05T07:54:19", - "tsCarCaptured": "2021-09-05T07:54:19", - "tsTssReceivedUtc": "2021-09-05T07:54:23Z", - "milCarCaptured": 25009, - "milCarSent": 25009, - "value": "1", - "textId": "tyre_invalid" - }, - { - "id": "0x0301060009", - "tsCarSentUtc": "2021-09-05T07:54:20Z", - "tsCarSent": "2021-09-05T07:54:19", - "tsCarCaptured": "2021-09-05T07:54:19", - "tsTssReceivedUtc": "2021-09-05T07:54:23Z", - "milCarCaptured": 25009, - "milCarSent": 25009, - "value": "1", - "textId": "tyre_invalid" - }, - { - "id": "0x030106000A", - "tsCarSentUtc": "2021-09-05T07:54:20Z", - "tsCarSent": "2021-09-05T07:54:19", - "tsCarCaptured": "2021-09-05T07:54:19", - "tsTssReceivedUtc": "2021-09-05T07:54:23Z", - "milCarCaptured": 25009, - "milCarSent": 25009, - "value": "1", - "textId": "tyre_invalid" - }, - { - "id": "0x030106000A", - "tsCarSentUtc": "2021-09-05T07:54:20Z", - "tsCarSent": "2021-09-05T07:54:19", - "tsCarCaptured": "2021-09-05T07:54:19", - "tsTssReceivedUtc": "2021-09-05T07:54:23Z", - "milCarCaptured": 25009, - "milCarSent": 25009, - "value": "1", - "textId": "tyre_invalid" - }, - { - "id": "0x030106000B", - "tsCarSentUtc": "2021-09-05T07:54:20Z", - "tsCarSent": "2021-09-05T07:54:19", - "tsCarCaptured": "2021-09-05T07:54:19", - "tsTssReceivedUtc": "2021-09-05T07:54:23Z", - "milCarCaptured": 25009, - "milCarSent": 25009, - "value": "1", - "textId": "tyre_invalid" - }, - { - "id": "0x030106000B", - "tsCarSentUtc": "2021-09-05T07:54:20Z", - "tsCarSent": "2021-09-05T07:54:19", - "tsCarCaptured": "2021-09-05T07:54:19", - "tsTssReceivedUtc": "2021-09-05T07:54:23Z", - "milCarCaptured": 25009, - "milCarSent": 25009, - "value": "1", - "textId": "tyre_invalid" - }, - { - "id": "0x030106000C", - "tsCarSentUtc": "2021-09-05T07:54:20Z", - "tsCarSent": "2021-09-05T07:54:19", - "tsCarCaptured": "2021-09-05T07:54:19", - "tsTssReceivedUtc": "2021-09-05T07:54:23Z", - "milCarCaptured": 25009, - "milCarSent": 25009, - "value": "1", - "textId": "tyre_invalid" - }, - { - "id": "0x030106000C", - "tsCarSentUtc": "2021-09-05T07:54:20Z", - "tsCarSent": "2021-09-05T07:54:19", - "tsCarCaptured": "2021-09-05T07:54:19", - "tsTssReceivedUtc": "2021-09-05T07:54:23Z", - "milCarCaptured": 25009, - "milCarSent": 25009, - "value": "1", - "textId": "tyre_invalid" - }, - { - "id": "0x030106000D", - "tsCarSentUtc": "2021-09-05T07:54:20Z", - "tsCarSent": "2021-09-05T07:54:19", - "tsCarCaptured": "2021-09-05T07:54:19", - "tsTssReceivedUtc": "2021-09-05T07:54:23Z", - "milCarCaptured": 25009, - "milCarSent": 25009, - "value": "1", - "textId": "tyre_invalid" - }, - { - "id": "0x030106000D", - "tsCarSentUtc": "2021-09-05T07:54:20Z", - "tsCarSent": "2021-09-05T07:54:19", - "tsCarCaptured": "2021-09-05T07:54:19", - "tsTssReceivedUtc": "2021-09-05T07:54:23Z", - "milCarCaptured": 25009, - "milCarSent": 25009, - "value": "1", - "textId": "tyre_invalid" - }, - { - "id": "0x030106000E", - "tsCarSentUtc": "2021-09-05T07:54:20Z", - "tsCarSent": "2021-09-05T07:54:19", - "tsCarCaptured": "2021-09-05T07:54:19", - "tsTssReceivedUtc": "2021-09-05T07:54:23Z", - "milCarCaptured": 25009, - "milCarSent": 25009, - "value": "1", - "textId": "tyre_invalid" - }, - { - "id": "0x030106000E", - "tsCarSentUtc": "2021-09-05T07:54:20Z", - "tsCarSent": "2021-09-05T07:54:19", - "tsCarCaptured": "2021-09-05T07:54:19", - "tsTssReceivedUtc": "2021-09-05T07:54:23Z", - "milCarCaptured": 25009, - "milCarSent": 25009, - "value": "1", - "textId": "tyre_invalid" - }, - { - "id": "0x030106000F", - "tsCarSentUtc": "2021-09-05T07:54:20Z", - "tsCarSent": "2021-09-05T07:54:19", - "tsCarCaptured": "2021-09-05T07:54:19", - "tsTssReceivedUtc": "2021-09-05T07:54:23Z", - "milCarCaptured": 25009, - "milCarSent": 25009, - "value": "1", - "textId": "tyre_invalid" - } - ] - } - ] - } - } -} diff --git a/vehicle/audi/types.go b/vehicle/audi/types.go deleted file mode 100644 index 92c0d2aff..000000000 --- a/vehicle/audi/types.go +++ /dev/null @@ -1,5 +0,0 @@ -package audi - -type Vehicle struct { - VIN, Type, Nickname string -} diff --git a/vehicle/seat-cupra.go b/vehicle/seat-cupra.go deleted file mode 100644 index ba130811f..000000000 --- a/vehicle/seat-cupra.go +++ /dev/null @@ -1,81 +0,0 @@ -package vehicle - -import ( - "context" - "fmt" - "time" - - "github.com/evcc-io/evcc/api" - "github.com/evcc-io/evcc/util" - "github.com/evcc-io/evcc/util/request" - "github.com/evcc-io/evcc/vehicle/seat/cupra" - "github.com/evcc-io/evcc/vehicle/vag/vwidentity" - "golang.org/x/oauth2" -) - -// Cupra is an api.Vehicle implementation for Seat Cupra cars -type Cupra struct { - *embed - *cupra.Provider // provides the api implementations -} - -func init() { - registry.Add("cupra", NewCupraFromConfig) -} - -// NewCupraFromConfig creates a new vehicle -func NewCupraFromConfig(other map[string]any) (api.Vehicle, error) { - cc := struct { - embed `mapstructure:",squash"` - User, Password, VIN string - Cache time.Duration - Timeout time.Duration - }{ - Cache: interval, - Timeout: request.Timeout, - } - - if err := util.DecodeOther(other, &cc); err != nil { - return nil, err - } - - if cc.User == "" || cc.Password == "" { - return nil, api.ErrMissingCredentials - } - - v := &Cupra{ - embed: &cc.embed, - } - - log := util.NewLogger("cupra").Redact(cc.User, cc.Password, cc.VIN) - - ts, err := vwidentity.Oauth2Login(log, cupra.OAuth2Config, cc.User, cc.Password) - if err != nil { - return nil, err - } - - // get OIDC user information - ctx := context.WithValue(context.Background(), oauth2.HTTPClient, request.NewClient(log)) - ui, err := vwidentity.Config.NewProvider(ctx).UserInfo(ctx, ts) - if err != nil { - return nil, fmt.Errorf("failed getting user information: %w", err) - } - - api := cupra.NewAPI(log, ts) - - vehicle, err := ensureVehicleEx( - cc.VIN, func() ([]cupra.Vehicle, error) { - return api.Vehicles(ui.Subject) - }, - func(v cupra.Vehicle) (string, error) { - return v.VIN, nil - }, - ) - - if err == nil { - v.fromVehicle(vehicle.VehicleNickname, 0) - v.Provider = cupra.NewProvider(api, ui.Subject, vehicle.VIN, cc.Cache) - } - - return v, err -} diff --git a/vehicle/seat.go b/vehicle/seat.go deleted file mode 100644 index f8f106ce5..000000000 --- a/vehicle/seat.go +++ /dev/null @@ -1,120 +0,0 @@ -package vehicle - -import ( - "context" - "fmt" - "net/http" - "net/url" - "strings" - "time" - - "github.com/evcc-io/evcc/api" - "github.com/evcc-io/evcc/util" - "github.com/evcc-io/evcc/util/request" - "github.com/evcc-io/evcc/vehicle/seat" - "github.com/evcc-io/evcc/vehicle/seat/cupra" - "github.com/evcc-io/evcc/vehicle/vag/service" - "github.com/evcc-io/evcc/vehicle/vag/vwidentity" - "github.com/evcc-io/evcc/vehicle/vw" - "golang.org/x/oauth2" -) - -// https://github.com/trocotronic/weconnect -// https://github.com/TA2k/ioBroker.vw-connect - -// Seat is an api.Vehicle implementation for Seat cars -type Seat struct { - *embed - *vw.Provider // provides the api implementations -} - -func init() { - registry.Add("seat", NewSeatFromConfig) -} - -// NewSeatFromConfig creates a new vehicle -func NewSeatFromConfig(other map[string]any) (api.Vehicle, error) { - cc := struct { - embed `mapstructure:",squash"` - User, Password, VIN string - Cache time.Duration - Timeout time.Duration - }{ - Cache: interval, - Timeout: request.Timeout, - } - - if err := util.DecodeOther(other, &cc); err != nil { - return nil, err - } - - if cc.User == "" || cc.Password == "" { - return nil, api.ErrMissingCredentials - } - - v := &Seat{ - embed: &cc.embed, - } - - log := util.NewLogger("seat").Redact(cc.User, cc.Password, cc.VIN) - - trs, err := vwidentity.Oauth2Login(log, cupra.OAuth2Config, cc.User, cc.Password) - if err != nil { - return nil, err - } - - // get OIDC user information - ctx := context.WithValue(context.Background(), oauth2.HTTPClient, request.NewClient(log)) - ui, err := vwidentity.Config.NewProvider(ctx).UserInfo(ctx, trs) - if err != nil { - return nil, fmt.Errorf("failed getting user information: %w", err) - } - - mbbId, err := mbbUserId(log, trs, ui.Subject) - if err != nil { - return nil, fmt.Errorf("failed getting mbbUserId: %w", err) - } - - ts := service.MbbTokenSource(log, trs, seat.AuthClientID) - api := seat.NewAPI(log, ts) - - cc.VIN, err = ensureVehicle( - cc.VIN, func() ([]string, error) { - return api.Vehicles(mbbId) - }, - ) - - if err == nil { - api := vw.NewAPI(log, ts, seat.Brand, seat.Country) - api.Client.Timeout = cc.Timeout - - if err = api.HomeRegion(cc.VIN); err == nil { - v.Provider = vw.NewProvider(api, cc.VIN, cc.Cache) - } - } - - return v, err -} - -func mbbUserId(log *util.Logger, ts oauth2.TokenSource, uid string) (string, error) { - client := request.NewHelper(log) - client.Transport = &oauth2.Transport{ - Source: ts, - Base: client.Transport, - } - - data := url.Values{"scopeId": {"commonMandatoryFields"}} - - var mandatoryConsentInfo struct { - MbbUserId string `json:"mbbUserId"` - } - - uri := fmt.Sprintf("https://profileintegrityservice.apps.emea.vwapps.io/iaa/pic/v1/users/%s/check-profile", uid) - req, err := request.New(http.MethodPost, uri, strings.NewReader(data.Encode()), request.URLEncoding) - - if err == nil { - err = client.DoJSON(req, &mandatoryConsentInfo) - } - - return mandatoryConsentInfo.MbbUserId, err -} diff --git a/vehicle/seat/api.go b/vehicle/seat/api.go deleted file mode 100644 index 36f8443ec..000000000 --- a/vehicle/seat/api.go +++ /dev/null @@ -1,53 +0,0 @@ -package seat - -import ( - "fmt" - - "github.com/evcc-io/evcc/util" - "github.com/evcc-io/evcc/util/request" - "golang.org/x/oauth2" -) - -// BaseURL is the API base url -const BaseURL = "https://mal-3a.prd.eu.dp.vwg-connect.com/api" - -// API provides list of vehicles for Seat cars -type API struct { - *request.Helper -} - -// NewAPI creates a new vehicle -func NewAPI(log *util.Logger, ts oauth2.TokenSource) *API { - v := &API{ - Helper: request.NewHelper(log), - } - - v.Client.Transport = &oauth2.Transport{ - Source: ts, - Base: v.Client.Transport, - } - - return v -} - -// Vehicles implements the /vehicles response -func (v *API) Vehicles(userID string) ([]string, error) { - var res struct { - UserVehicles struct { - UserId string - Vehicle []struct { - Content string - } - } - } - - uri := fmt.Sprintf("%s/usermanagement/users/v2/users/%s/vehicles", BaseURL, userID) - err := v.GetJSON(uri, &res) - - var vehicles []string - for _, v := range res.UserVehicles.Vehicle { - vehicles = append(vehicles, v.Content) - } - - return vehicles, err -} diff --git a/vehicle/seat/cupra/api.go b/vehicle/seat/cupra/api.go deleted file mode 100644 index be467509b..000000000 --- a/vehicle/seat/cupra/api.go +++ /dev/null @@ -1,99 +0,0 @@ -package cupra - -import ( - "fmt" - "net/http" - - "github.com/evcc-io/evcc/util" - "github.com/evcc-io/evcc/util/request" - "github.com/evcc-io/evcc/util/transport" - "golang.org/x/oauth2" -) - -const ( - // BaseURL is the API base url - BaseURL = "https://ola.prod.code.seat.cloud.vwgroup.com" - - ActionCharge = "charging" - ActionChargeStart = "start" - ActionChargeStop = "stop" - - // appVersion is the Cupra app version mirrored in request headers - appVersion = "2.15.0" -) - -// API is an api.Vehicle implementation for Seat Cupra cars -type API struct { - *request.Helper -} - -// NewAPI creates a new vehicle -func NewAPI(log *util.Logger, ts oauth2.TokenSource) *API { - v := &API{ - Helper: request.NewHelper(log), - } - - v.Client.Transport = &transport.Decorator{ - Base: &oauth2.Transport{ - Source: ts, - Base: v.Client.Transport, - }, - // These headers mirror the official Cupra app and are required to avoid - // 403 Forbidden from the OLA backend (verified against pycupra v0.2.30). - Decorator: transport.DecorateHeaders(map[string]string{ - "app-market": "android", - "app-brand": "cupra", - "app-version": appVersion, - "User-Agent": "OLACupra/" + appVersion + " (Android 12; sdk_gphone64_x86_64; Google) Mobile", - "origin": "app", - }), - } - - return v -} - -// Vehicles implements the /vehicles response -func (v *API) Vehicles(userID string) ([]Vehicle, error) { - var res struct { - Vehicles []Vehicle - } - - uri := fmt.Sprintf("%s/v2/users/%s/garage/vehicles", BaseURL, userID) - err := v.GetJSON(uri, &res) - - return res.Vehicles, err -} - -// Status implements the /status response -func (v *API) Status(userID, vin string) (Status, error) { - var res Status - uri := fmt.Sprintf("%s/v5/users/%s/vehicles/%s/mycar", BaseURL, userID, vin) - err := v.GetJSON(uri, &res) - return res, err -} - -// ParkingPosition implements the /parkingposition response -func (v *API) ParkingPosition(vin string) (Position, error) { - var res Position - uri := fmt.Sprintf("%s/v1/vehicles/%s/parkingposition", BaseURL, vin) - err := v.GetJSON(uri, &res) - return res, err -} - -// Mileage implements the /mileage response -func (v *API) Mileage(vin string) (Mileage, error) { - var res Mileage - uri := fmt.Sprintf("%s/v1/vehicles/%s/mileage", BaseURL, vin) - err := v.GetJSON(uri, &res) - return res, err -} - -// Action implements the /requests response -func (v *API) Action(vin, action, cmd string) error { - uri := fmt.Sprintf("%s/vehicles/%s/%s/requests/%s", BaseURL, vin, action, cmd) - req, err := request.New(http.MethodPost, uri, nil, request.JSONEncoding) - if err == nil { - _, err = v.DoBody(req) - } - return err -} diff --git a/vehicle/seat/cupra/params.go b/vehicle/seat/cupra/params.go deleted file mode 100644 index 7bc04e717..000000000 --- a/vehicle/seat/cupra/params.go +++ /dev/null @@ -1,12 +0,0 @@ -package cupra - -import ( - "golang.org/x/oauth2" -) - -var OAuth2Config = &oauth2.Config{ - ClientID: "3c756d46-f1ba-4d78-9f9a-cff0d5292d51@apps_vw-dilab_com", - ClientSecret: "eb8814e641c81a2640ad62eeccec11c98effc9bccd4269ab7af338b50a94b3a2", - RedirectURL: "cupra://oauth-callback", - Scopes: []string{"openid", "profile", "mbb"}, -} diff --git a/vehicle/seat/cupra/provider.go b/vehicle/seat/cupra/provider.go deleted file mode 100644 index 984a8d5ae..000000000 --- a/vehicle/seat/cupra/provider.go +++ /dev/null @@ -1,164 +0,0 @@ -package cupra - -import ( - "strings" - "time" - - "github.com/evcc-io/evcc/api" - "github.com/evcc-io/evcc/util" -) - -// Provider is an api.Vehicle implementation for Seat Cupra cars -type Provider struct { - statusG func() (Status, error) - positionG func() (Position, error) - milageG func() (Mileage, error) - action func(string, string) error -} - -// NewProvider creates a vehicle api provider -func NewProvider(api *API, userID, vin string, cache time.Duration) *Provider { - impl := &Provider{ - statusG: util.Cached(func() (Status, error) { - return api.Status(userID, vin) - }, cache), - positionG: util.Cached(func() (Position, error) { - return api.ParkingPosition(vin) - }, cache), - milageG: util.Cached(func() (Mileage, error) { - return api.Mileage(vin) - }, cache), - action: func(action, cmd string) error { - return api.Action(vin, action, cmd) - }, - } - return impl -} - -var _ api.Battery = (*Provider)(nil) - -func (v *Provider) engine(s Status, typ string) (Engine, error) { - for _, e := range []Engine{s.Engines.Primary, s.Engines.Secondary} { - if e.FuelType == typ { - return e, nil - } - } - return Engine{}, api.ErrNotAvailable -} - -// Soc implements the api.Vehicle interface -func (v *Provider) Soc() (float64, error) { - res, err := v.statusG() - if err != nil { - return 0, err - } - - engine, err := v.engine(res, FuelTypeElectric) - return engine.LevelPct, err -} - -var _ api.ChargeState = (*Provider)(nil) - -// Status implements the api.ChargeState interface -func (v *Provider) Status() (api.ChargeStatus, error) { - res, err := v.statusG() - if err != nil { - return api.StatusNone, err - } - - // BatteryCardStatus is the authoritative disconnect signal — the Cupra API - // only emits "notConnected" when the cable is unplugged. When the car is - // plugged the field is omitted and Status alone is unreliable: it reports - // "NotReadyForCharging" both for an unplugged car. - // https://github.com/evcc-io/evcc/issues/30045 - if strings.ToLower(res.Services.Charging.BatteryCardStatus) == "notconnected" { - return api.StatusA, nil - } - - switch strings.ToLower(res.Services.Charging.Status) { - case "connected", "readyforcharging", "notreadyforcharging", "error", "chargepurposereachedandnotconservationcharging": - return api.StatusB, nil - case "charging": - return api.StatusC, nil - } - - return api.StatusA, nil -} - -var _ api.VehicleFinishTimer = (*Provider)(nil) - -// FinishTime implements the api.VehicleFinishTimer interface -func (v *Provider) FinishTime() (time.Time, error) { - res, err := v.statusG() - if err != nil { - return time.Time{}, err - } - - rsc := res.Services.Charging - if !rsc.Active { - return time.Time{}, api.ErrNotAvailable - } - - rt := rsc.RemainingTime - if rsc.TargetPct > 0 && rsc.TargetPct < 100 { - rt = rt * 100 / int64(rsc.TargetPct) - } - - return time.Now().Add(time.Duration(rt) * time.Minute), nil -} - -var _ api.VehicleRange = (*Provider)(nil) - -// Range implements the api.VehicleRange interface -func (v *Provider) Range() (int64, error) { - res, err := v.statusG() - if err != nil { - return 0, err - } - - engine, err := v.engine(res, FuelTypeElectric) - return int64(engine.RangeKm), err -} - -var _ api.VehicleOdometer = (*Provider)(nil) - -// Odometer implements the api.VehicleOdometer interface -func (v *Provider) Odometer() (float64, error) { - res, err := v.milageG() - return res.MileageKm, err -} - -var _ api.VehiclePosition = (*Provider)(nil) - -// Position implements the api.VehiclePosition interface -func (v *Provider) Position() (float64, float64, error) { - res, err := v.positionG() - return res.Lat, res.Lon, err -} - -var _ api.VehicleClimater = (*Provider)(nil) - -// Climater implements the api.VehicleClimater interface -func (v *Provider) Climater() (bool, error) { - res, err := v.statusG() - return res.Services.Climatisation.Active, err -} - -var _ api.SocLimiter = (*Provider)(nil) - -// GetLimitSoc implements the api.SocLimiter interface -func (v *Provider) GetLimitSoc() (int64, error) { - res, err := v.statusG() - if err == nil && res.Services.Charging.ChargeSettings == "profile" { - return 0, api.ErrNotAvailable - } - return int64(res.Services.Charging.TargetPct), err -} - -var _ api.ChargeController = (*Provider)(nil) - -// ChargeEnable implements the api.ChargeController interface -func (v *Provider) ChargeEnable(enable bool) error { - action := map[bool]string{true: ActionChargeStart, false: ActionChargeStop} - return v.action(ActionCharge, action[enable]) -} diff --git a/vehicle/seat/cupra/provider_test.go b/vehicle/seat/cupra/provider_test.go deleted file mode 100644 index 22974c8b5..000000000 --- a/vehicle/seat/cupra/provider_test.go +++ /dev/null @@ -1,55 +0,0 @@ -package cupra - -import ( - "testing" - - "github.com/evcc-io/evcc/api" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" -) - -// TestProviderStatus covers the Cupra v5 charging-status payload variants -// captured in issues #30045 and #30118. -func TestProviderStatus(t *testing.T) { - cases := []struct { - name string - statusField string - batteryCardStatus string - want api.ChargeStatus - }{ - // cable not plugged in: API emits batteryCardStatus=notConnected - {"unplugged", "NotReadyForCharging", "notConnected", api.StatusA}, - // charging: API omits batteryCardStatus - {"charging", "Charging", "", api.StatusC}, - // plugged but not charging (e.g. chargeMode=off): API omits - // batteryCardStatus, Status reports NotReadyForCharging — must NOT be - // misread as disconnected (#30118) - {"plugged_paused", "NotReadyForCharging", "", api.StatusB}, - // plugged, ready to charge but not yet started - {"ready", "ReadyForCharging", "", api.StatusB}, - // already-connected pre-v5 payload - {"connected", "Connected", "", api.StatusB}, - // fault / error while plugged - {"error", "error", "", api.StatusB}, - // target SoC reached in myCupra, cable still connected (#30118) - {"soc_reached", "ChargePurposeReachedAndNotConservationCharging", "", api.StatusB}, - // unknown future status with no card info defaults to disconnected - {"unknown", "SomethingNew", "", api.StatusA}, - } - - for _, tc := range cases { - t.Run(tc.name, func(t *testing.T) { - var s Status - s.Services.Charging.Status = tc.statusField - s.Services.Charging.BatteryCardStatus = tc.batteryCardStatus - - v := &Provider{ - statusG: func() (Status, error) { return s, nil }, - } - - got, err := v.Status() - require.NoError(t, err) - assert.Equal(t, tc.want, got) - }) - } -} diff --git a/vehicle/seat/cupra/types.go b/vehicle/seat/cupra/types.go deleted file mode 100644 index 3709ea31f..000000000 --- a/vehicle/seat/cupra/types.go +++ /dev/null @@ -1,53 +0,0 @@ -package cupra - -const FuelTypeElectric = "electric" - -type Vehicle struct { - VIN string - EnrollmentStatus string - UserRole string - VehicleNickname string -} - -type Engine struct { - Type string - FuelType string - RangeKm float64 - LevelPct float64 -} - -type Status struct { - Engines struct { - Primary, Secondary Engine - } - Services struct { - Charging struct { - Status string - BatteryCardStatus string - TargetPct int - ChargeMode string - ChargeSettings string - Active bool - RemainingTime int64 - CurrentPct float64 - ProgressBarPct float64 - } - Climatisation struct { - Status string - Active bool - RemainingTime int64 - ProgressBarPct float64 - } - } - Measurements struct { - MileageKm float64 - } -} - -type Mileage struct { - MileageKm float64 -} - -type Position struct { - Lat, Lon float64 -} diff --git a/vehicle/seat/params.go b/vehicle/seat/params.go deleted file mode 100644 index ff58ab104..000000000 --- a/vehicle/seat/params.go +++ /dev/null @@ -1,19 +0,0 @@ -package seat - -import "net/url" - -const ( - Brand = "VW" - Country = "ES" - - // Authorization ClientID - AuthClientID = "9dcc70f0-8e79-423a-a3fa-4065d99088b4" -) - -// Authorization parameters -var AuthParams = url.Values{ - "response_type": {"code id_token"}, // token - "client_id": {"3c8e98bc-3ae9-4277-a563-d5ee65ddebba@apps_vw-dilab_com"}, - "redirect_uri": {"seatconnect://identity-kit/login"}, - "scope": {"openid profile"}, // address phone email birthdate nationalIdentifier cars mbb dealers badge nationality -} diff --git a/vehicle/vag/aazsproxy/endpoint.go b/vehicle/vag/aazsproxy/endpoint.go deleted file mode 100644 index 3b4f4df2c..000000000 --- a/vehicle/vag/aazsproxy/endpoint.go +++ /dev/null @@ -1,54 +0,0 @@ -package aazsproxy - -import ( - "net/http" - - "github.com/evcc-io/evcc/util" - "github.com/evcc-io/evcc/util/request" - "github.com/evcc-io/evcc/vehicle/vag" - "github.com/evcc-io/evcc/vehicle/vag/cariad" - "golang.org/x/oauth2" -) - -var Endpoint = &oauth2.Endpoint{ - AuthURL: cariad.BaseURL + "/login/v1/audi/token", -} - -type Service struct { - *request.Helper -} - -func New(log *util.Logger) *Service { - return &Service{ - Helper: request.NewHelper(log), - } -} - -// Exchange exchanges an VAG identity or IDK token for an AAZS token -func (v *Service) Exchange(config, token string) (*vag.Token, error) { - data := struct { - Token string `json:"token"` - GrantType string `json:"grant_type"` - Stage string `json:"stage"` - Config string `json:"config"` - }{ - Token: token, - GrantType: "id_token", - Stage: "live", - Config: config, - } - - var res vag.Token - - req, err := request.New(http.MethodPost, Endpoint.AuthURL, request.MarshalJSON(data), request.JSONEncoding) - if err == nil { - err = v.DoJSON(req, &res) - } - - return &res, err -} - -// TokenSource creates token source. Token is NOT refreshed but will expire. -func (v *Service) TokenSource(token *vag.Token) vag.TokenSource { - return vag.RefreshTokenSource(token, nil) -} diff --git a/vehicle/vag/cariad/const.go b/vehicle/vag/cariad/const.go deleted file mode 100644 index 13cfa9a1e..000000000 --- a/vehicle/vag/cariad/const.go +++ /dev/null @@ -1,8 +0,0 @@ -package cariad - -const ( - BaseURL = "https://emea.bff.cariad.digital" - AndroidPackageName = "com.volkswagen.weconnect" - UserAgent = "Volkswagen/3.51.1-android/14" - ClientID = "a24fba63-34b3-4d43-b181-942111e6bda8@apps_vw-dilab_com" -) diff --git a/vehicle/vag/idkproxy/endpoint.go b/vehicle/vag/idkproxy/endpoint.go deleted file mode 100644 index 14d821a54..000000000 --- a/vehicle/vag/idkproxy/endpoint.go +++ /dev/null @@ -1,124 +0,0 @@ -package idkproxy - -import ( - "crypto/hmac" - "crypto/sha256" - "encoding/hex" - "net/http" - "net/url" - "strconv" - "strings" - "time" - - "github.com/coreos/go-oidc/v3/oidc" - "github.com/evcc-io/evcc/util" - "github.com/evcc-io/evcc/util/request" - "github.com/evcc-io/evcc/util/urlvalues" - "github.com/evcc-io/evcc/vehicle/vag" - "github.com/evcc-io/evcc/vehicle/vag/cariad" -) - -const WellKnown = cariad.BaseURL + "/auth/v1/idk/oidc/openid-configuration" - -var Config = &oidc.ProviderConfig{ - AuthURL: "https://identity.vwgroup.io/oidc/v1/authorize", - TokenURL: cariad.BaseURL + "/auth/v1/idk/oidc/token", -} - -var _ vag.TokenExchanger = (*Service)(nil) - -type Service struct { - *request.Helper - data url.Values -} - -func New(log *util.Logger, q url.Values) *Service { - return &Service{ - Helper: request.NewHelper(log), - data: q, - } -} - -// https://github.com/arjenvrh/audi_connect_ha/issues/133 - -const ( - qmSecret = "1ab69925ac179aaa4e83abe671a9476d176418b85bd706f1436ca15be647989c" - qmClientId = "01da27b0" - userAgent = "Android/4.31.0 (Build 800341641.root project 'myaudi_android'.ext.buildTime) Android/13" -) - -func qmauth(ts int64) string { - secret, _ := hex.DecodeString(qmSecret) - hash := hmac.New(sha256.New, secret) - hash.Write([]byte(strconv.FormatInt(ts, 10))) - return hex.EncodeToString(hash.Sum(nil)) -} - -func qmauthNow() string { - return "v1:" + qmClientId + ":" + qmauth(time.Now().Unix()/100) -} - -// tokenHeaders returns the assertion header set the IDK token endpoint -// validates for both authorization_code and refresh_token grants. -func tokenHeaders() map[string]string { - return map[string]string{ - "Content-Type": request.FormContent, - "Accept": request.JSONContent, - "Accept-Charset": "utf-8", - "User-Agent": userAgent, - "x-qmauth": qmauthNow(), - "x-platform": "android", - "x-android-package-name": "de.myaudi.mobile.assistant", - "x-assertion": "0", - } -} - -// Exchange exchanges an VAG identity token for an IDK token -func (v *Service) Exchange(q url.Values) (*vag.Token, error) { - if err := urlvalues.Require(q, "code", "code_verifier"); err != nil { - return nil, err - } - - data := url.Values{ - "grant_type": {"authorization_code"}, - "response_type": {"token id_token"}, - "code": {q.Get("code")}, - "code_verifier": {q.Get("code_verifier")}, - } - - urlvalues.Merge(data, v.data) - - var res vag.Token - - req, err := request.New(http.MethodPost, Config.TokenURL, strings.NewReader(data.Encode()), tokenHeaders()) - if err == nil { - err = v.DoJSON(req, &res) - } - - return &res, err -} - -// Refresh refreshes an IDK token -func (v *Service) Refresh(token *vag.Token) (*vag.Token, error) { - data := url.Values{ - "grant_type": {"refresh_token"}, - "response_type": {"token id_token"}, - "refresh_token": {token.RefreshToken}, - } - - urlvalues.Merge(data, v.data) - - var res vag.Token - - req, err := request.New(http.MethodPost, Config.TokenURL, strings.NewReader(data.Encode()), tokenHeaders()) - if err == nil { - err = v.DoJSON(req, &res) - } - - return &res, err -} - -// TokenSource creates token source. Token is refreshed automatically. -func (v *Service) TokenSource(token *vag.Token) vag.TokenSource { - return vag.RefreshTokenSource(token, v.Refresh) -} diff --git a/vehicle/vag/mbb/endpoint.go b/vehicle/vag/mbb/endpoint.go deleted file mode 100644 index 9dd3aad36..000000000 --- a/vehicle/vag/mbb/endpoint.go +++ /dev/null @@ -1,86 +0,0 @@ -package mbb - -import ( - "fmt" - "net/http" - "net/url" - "strings" - - "github.com/evcc-io/evcc/util" - "github.com/evcc-io/evcc/util/request" - "github.com/evcc-io/evcc/util/urlvalues" - "github.com/evcc-io/evcc/vehicle/vag" -) - -const ( - BaseURL = "https://mbboauth-1d.prd.ece.vwg-connect.com" - TokenURL = BaseURL + "/mbbcoauth/mobile/oauth2/v1/token" -) - -var _ vag.TokenExchanger = (*Service)(nil) - -type Service struct { - *request.Helper - clientID string -} - -func New(log *util.Logger, clientID string) *Service { - return &Service{ - Helper: request.NewHelper(log), - clientID: clientID, - } -} - -func (v *Service) Exchange(q url.Values) (*vag.Token, error) { - if err := urlvalues.Require(q, "id_token"); err != nil { - return nil, err - } - - data := url.Values{ - "grant_type": {"id_token"}, - "token": {q.Get("id_token")}, - "scope": {"sc2:fal"}, - } - - req, err := request.New(http.MethodPost, TokenURL, strings.NewReader(data.Encode()), map[string]string{ - "Content-Type": "application/x-www-form-urlencoded", - "X-Client-Id": v.clientID, - }) - - var res vag.Token - if err == nil { - err = v.DoJSON(req, &res) - } - - // check if token response contained error - if errT := res.Error(); err != nil && errT != nil { - err = fmt.Errorf("token exchange: %w", errT) - } - - return &res, err -} - -func (v *Service) Refresh(token *vag.Token) (*vag.Token, error) { - data := url.Values{ - "grant_type": {"refresh_token"}, - "refresh_token": {token.RefreshToken}, - "scope": {"sc2:fal"}, - } - - req, err := request.New(http.MethodPost, TokenURL, strings.NewReader(data.Encode()), map[string]string{ - "Content-Type": "application/x-www-form-urlencoded", - "X-Client-Id": v.clientID, - }) - - var res vag.Token - if err == nil { - err = v.DoJSON(req, &res) - } - - return &res, err -} - -// TokenSource creates token source. Token is refreshed automatically. -func (v *Service) TokenSource(token *vag.Token) vag.TokenSource { - return vag.RefreshTokenSource(token, v.Refresh) -} diff --git a/vehicle/vag/service/azs.go b/vehicle/vag/service/azs.go deleted file mode 100644 index 1c226dfb9..000000000 --- a/vehicle/vag/service/azs.go +++ /dev/null @@ -1,42 +0,0 @@ -package service - -import ( - "net/url" - - "github.com/evcc-io/evcc/util" - "github.com/evcc-io/evcc/vehicle/vag" - "github.com/evcc-io/evcc/vehicle/vag/aazsproxy" -) - -// AAZSTokenSource creates a refreshing token source for use with the AAZS api. -// Once the AAZS token expires, it is recreated from the token exchanger (either TokenRefreshService or IDK). -// Return values are the AAZS and token exchanger (TRS or IDK) token sources. -func AAZSTokenSource(log *util.Logger, tox vag.TokenExchanger, azsConfig string, q url.Values) (vag.TokenSource, vag.TokenSource, error) { - token, err := tox.Exchange(q) - if err != nil { - return nil, nil, err - } - - trs := tox.TokenSource(token) - azs := aazsproxy.New(log) - - mts := vag.MetaTokenSource(func() (*vag.Token, error) { - // get TRS token from refreshing TRS token source - itoken, err := trs.TokenEx() - if err != nil { - return nil, err - } - - // exchange TRS id_token for AAZS token - atoken, err := azs.Exchange(azsConfig, itoken.IDToken) - if err != nil { - return nil, err - } - - return atoken, err - - // produce tokens from refresh MBB token source - }, azs.TokenSource) - - return mts, trs, nil -} diff --git a/vehicle/vag/service/mbb.go b/vehicle/vag/service/mbb.go deleted file mode 100644 index c2767400d..000000000 --- a/vehicle/vag/service/mbb.go +++ /dev/null @@ -1,33 +0,0 @@ -package service - -import ( - "net/url" - - "github.com/evcc-io/evcc/util" - "github.com/evcc-io/evcc/vehicle/vag" - "github.com/evcc-io/evcc/vehicle/vag/mbb" -) - -// MbbTokenSource creates a refreshing token source for use with the MBB api. -// Once the MBB token expires, it is recreated from the token exchanger (either TokenRefreshService or IDK) -func MbbTokenSource(log *util.Logger, trs vag.TokenSource, clientID string) vag.TokenSource { - mbb := mbb.New(log, clientID) - - return vag.MetaTokenSource(func() (*vag.Token, error) { - // get TRS token from refreshing TRS token source - itoken, err := trs.TokenEx() - if err != nil { - return nil, err - } - - // exchange TRS id_token for MBB token - mtoken, err := mbb.Exchange(url.Values{"id_token": {itoken.IDToken}}) - if err != nil { - return nil, err - } - - return mtoken, err - - // produce tokens from refresh MBB token source - }, mbb.TokenSource) -} diff --git a/vehicle/vw.go b/vehicle/vw.go deleted file mode 100644 index 4d5b3c92d..000000000 --- a/vehicle/vw.go +++ /dev/null @@ -1,77 +0,0 @@ -package vehicle - -import ( - "time" - - "github.com/evcc-io/evcc/api" - "github.com/evcc-io/evcc/util" - "github.com/evcc-io/evcc/util/request" - "github.com/evcc-io/evcc/vehicle/vag/vwidentity" - "github.com/evcc-io/evcc/vehicle/vw/weconnect" -) - -// https://github.com/TA2k/ioBroker.vw-connect - -// VW is an api.Vehicle implementation for ID cars -type VW struct { - *embed - *weconnect.Provider // provides the api implementations -} - -func init() { - registry.Add("vw", NewVWFromConfig) -} - -// NewVWFromConfig creates a new vehicle -func NewVWFromConfig(other map[string]any) (api.Vehicle, error) { - cc := struct { - embed `mapstructure:",squash"` - User, Password, VIN string - Cache time.Duration - Timeout time.Duration - }{ - Cache: interval, - Timeout: request.Timeout, - } - - if err := util.DecodeOther(other, &cc); err != nil { - return nil, err - } - - if cc.User == "" || cc.Password == "" { - return nil, api.ErrMissingCredentials - } - - v := &VW{ - embed: &cc.embed, - } - - log := util.NewLogger("vw").Redact(cc.User, cc.Password, cc.VIN) - - q, err := vwidentity.Login(log, weconnect.AuthParams, cc.User, cc.Password) - if err != nil { - return nil, err - } - - token, err := weconnect.ExchangeCode(log, q) - if err != nil { - return nil, err - } - - api := weconnect.NewAPI(log, weconnect.TokenSource(log, token)) - api.Client.Timeout = cc.Timeout - - vehicle, err := ensureVehicleEx( - cc.VIN, api.Vehicles, - func(v weconnect.Vehicle) (string, error) { - return v.VIN, nil - }, - ) - - if err == nil { - v.fromVehicle(vehicle.Nickname, 0) - v.Provider = weconnect.NewProvider(api, vehicle.VIN, cc.Cache) - } - - return v, err -} diff --git a/vehicle/vw/api.go b/vehicle/vw/api.go deleted file mode 100644 index a047b9207..000000000 --- a/vehicle/vw/api.go +++ /dev/null @@ -1,218 +0,0 @@ -package vw - -import ( - "errors" - "fmt" - "net/http" - "strings" - - "github.com/evcc-io/evcc/util" - "github.com/evcc-io/evcc/util/request" - "golang.org/x/oauth2" -) - -// DefaultBaseURI is the VW api base URI -const DefaultBaseURI = "https://msg.volkswagen.de/fs-car" - -// RegionAPI is the VW api used for determining the home region -const RegionAPI = "https://mal-1a.prd.ece.vwg-connect.com/api" - -// API is the VW api client -type API struct { - *request.Helper - brand, country string - baseURI string - statusURI string -} - -// NewAPI creates a new api client -func NewAPI(log *util.Logger, ts oauth2.TokenSource, brand, country string) *API { - v := &API{ - Helper: request.NewHelper(log), - brand: brand, - country: country, - baseURI: DefaultBaseURI, - } - - v.Client.Transport = &oauth2.Transport{ - Source: ts, - Base: v.Client.Transport, - } - - return v -} - -// HomeRegion updates the home region for the given vehicle -func (v *API) HomeRegion(vin string) error { - var res HomeRegion - uri := fmt.Sprintf("%s/cs/vds/v1/vehicles/%s/homeRegion", RegionAPI, vin) - - err := v.GetJSON(uri, &res) - if err == nil { - if api := res.HomeRegion.BaseURI.Content; strings.HasPrefix(api, "https://mal-3a.prd.eu.dp.vwg-connect.com") { - api = "https://fal" + strings.TrimPrefix(api, "https://mal") - api = strings.TrimSuffix(api, "/api") + "/fs-car" - v.baseURI = api - } - } else if res.Error != nil { - err = res.Error.Error() - } - - return err -} - -// RolesRights implements the /rolesrights/operationlist response -func (v *API) RolesRights(vin string) (RolesRights, error) { - var res RolesRights - uri := fmt.Sprintf("%s/rolesrights/operationlist/v3/vehicles/%s", RegionAPI, vin) - err := v.GetJSON(uri, &res) - return res, err -} - -// ServiceURI renders the service URI for the given vin and service -func (v *API) ServiceURI(vin, service string, rr RolesRights) (uri string) { - if si := rr.ServiceByID(service); si != nil { - uri = si.InvocationUrl.Content - uri = strings.ReplaceAll(uri, "{vin}", vin) - uri = strings.ReplaceAll(uri, "{brand}", v.brand) - uri = strings.ReplaceAll(uri, "{country}", v.country) - } - - return uri -} - -// Status implements the /status response -func (v *API) Status(vin string) (StatusResponse, error) { - var res StatusResponse - uri := fmt.Sprintf("%s/bs/vsr/v1/vehicles/%s/status", RegionAPI, vin) - if v.statusURI != "" { - uri = v.statusURI - } - - headers := map[string]string{ - "Accept": request.JSONContent, - "X-App-Name": "foo", // required - "X-App-Version": "foo", // required - } - - req, err := request.New(http.MethodGet, uri, nil, headers) - if err == nil { - err = v.DoJSON(req, &res) - } - - if _, ok := errors.AsType[*request.StatusError](err); ok { - var rr RolesRights - rr, err = v.RolesRights(vin) - - if err == nil { - if uri = v.ServiceURI(vin, StatusService, rr); uri == "" { - err = fmt.Errorf("%s not found", StatusService) - } - } - - if err == nil { - if strings.HasSuffix(uri, fmt.Sprintf("%s/", vin)) { - uri += "status" - } - - if req, err = request.New(http.MethodGet, uri, nil, headers); err == nil { - if err = v.DoJSON(req, &res); err == nil { - v.statusURI = uri - } - } - } - } - - return res, err -} - -// Charger implements the /charger response -func (v *API) Charger(vin string) (ChargerResponse, error) { - var res ChargerResponse - uri := fmt.Sprintf("%s/bs/batterycharge/v1/%s/%s/vehicles/%s/charger", v.baseURI, v.brand, v.country, vin) - err := v.GetJSON(uri, &res) - if err != nil && res.Error != nil { - err = res.Error.Error() - } - return res, err -} - -// Climater implements the /climater response -func (v *API) Climater(vin string) (ClimaterResponse, error) { - var res ClimaterResponse - uri := fmt.Sprintf("%s/bs/climatisation/v1/%s/%s/vehicles/%s/climater", v.baseURI, v.brand, v.country, vin) - err := v.GetJSON(uri, &res) - if err != nil && res.Error != nil { - err = res.Error.Error() - } - return res, err -} - -// Position implements the /position response -func (v *API) Position(vin string) (PositionResponse, error) { - var res PositionResponse - uri := fmt.Sprintf("%s/bs/cf/v1/%s/%s/vehicles/%s/position", v.baseURI, v.brand, v.country, vin) - - req, err := request.New(http.MethodGet, uri, nil, map[string]string{ - "Accept": request.JSONContent, - "Content-type": "application/vnd.vwg.mbb.carfinderservice_v1_0_0+json", - "X-App-Name": "foo", // required - "X-App-Version": "foo", // required - }) - if err == nil { - err = v.DoJSON(req, &res) - } - - if err != nil && res.Error != nil { - err = res.Error.Error() - } - - return res, err -} - -const ( - ActionCharge = "batterycharge" - ActionChargeStart = "start" - ActionChargeStop = "stop" -) - -type actionDefinition struct { - contentType string - appendix string -} - -var actionDefinitions = map[string]actionDefinition{ - ActionCharge: { - "application/vnd.vwg.mbb.ChargerAction_v1_0_0+xml", - "charger/actions", - }, -} - -// Action implements vehicle actions -func (v *API) Action(vin, action, value string) error { - def := actionDefinitions[action] - - uri := fmt.Sprintf("%s/bs/%s/v1/%s/%s/vehicles/%s/%s", v.baseURI, action, v.brand, v.country, vin, def.appendix) - body := "" + value + "" - - req, err := request.New(http.MethodPost, uri, strings.NewReader(body), map[string]string{ - "Content-type": def.contentType, - }) - - if err == nil { - var resp *http.Response - if resp, err = v.Do(req); err == nil { - resp.Body.Close() - } - } - - return err -} - -// Any implements any api response -func (v *API) Any(base, vin string) (any, error) { - var res any - uri := fmt.Sprintf("%s/"+strings.TrimLeft(base, "/"), v.baseURI, v.brand, v.country, vin) - err := v.GetJSON(uri, &res) - return res, err -} diff --git a/vehicle/vw/provider.go b/vehicle/vw/provider.go deleted file mode 100644 index 025055359..000000000 --- a/vehicle/vw/provider.go +++ /dev/null @@ -1,204 +0,0 @@ -package vw - -import ( - "cmp" - "fmt" - "os" - "slices" - "strconv" - "strings" - "text/tabwriter" - "time" - - "github.com/evcc-io/evcc/api" - "github.com/evcc-io/evcc/util" - "github.com/samber/lo" -) - -// Provider implements the vehicle api -type Provider struct { - chargerG func() (ChargerResponse, error) - statusG func() (StatusResponse, error) - climateG func() (ClimaterResponse, error) - positionG func() (PositionResponse, error) - action func(action, value string) error - rr func() (RolesRights, error) -} - -// NewProvider creates a vehicle api provider -func NewProvider(api *API, vin string, cache time.Duration) *Provider { - impl := &Provider{ - chargerG: util.Cached(func() (ChargerResponse, error) { - return api.Charger(vin) - }, cache), - statusG: util.Cached(func() (StatusResponse, error) { - return api.Status(vin) - }, cache), - climateG: util.Cached(func() (ClimaterResponse, error) { - return api.Climater(vin) - }, cache), - positionG: util.Cached(func() (PositionResponse, error) { - return api.Position(vin) - }, cache), - action: func(action, value string) error { - return api.Action(vin, action, value) - }, - rr: func() (RolesRights, error) { - return api.RolesRights(vin) - }, - } - return impl -} - -var _ api.Battery = (*Provider)(nil) - -// Soc implements the api.Vehicle interface -func (v *Provider) Soc() (float64, error) { - res, err := v.chargerG() - if err == nil { - return float64(res.Charger.Status.BatteryStatusData.StateOfCharge.Content), nil - } - return 0, err -} - -var _ api.ChargeState = (*Provider)(nil) - -// Status implements the api.ChargeState interface -func (v *Provider) Status() (api.ChargeStatus, error) { - status := api.StatusA // disconnected - - res, err := v.chargerG() - if err == nil { - if res.Charger.Status.PlugStatusData.PlugState.Content == "connected" { - status = api.StatusB - } - if res.Charger.Status.ChargingStatusData.ChargingState.Content == "charging" { - status = api.StatusC - } - } - - return status, err -} - -var _ api.VehicleFinishTimer = (*Provider)(nil) - -// FinishTime implements the api.VehicleFinishTimer interface -func (v *Provider) FinishTime() (time.Time, error) { - res, err := v.chargerG() - if err == nil { - rct := res.Charger.Status.BatteryStatusData.RemainingChargingTime - - // estimate not available - if rct.Content == 65535 { - return time.Time{}, api.ErrNotAvailable - } - - return time.Now().Add(time.Duration(rct.Content) * time.Minute), nil - } - - return time.Time{}, err -} - -var _ api.VehicleRange = (*Provider)(nil) - -// Range implements the api.VehicleRange interface -func (v *Provider) Range() (rng int64, err error) { - res, err := v.chargerG() - if err == nil { - crsd := res.Charger.Status.CruisingRangeStatusData - - rng = int64(crsd.PrimaryEngineRange.Content) - if crsd.EngineTypeFirstEngine.Content != "typeIsElectric" { - rng = int64(crsd.SecondaryEngineRange.Content) - } - } - - return rng, err -} - -var _ api.VehicleOdometer = (*Provider)(nil) - -// Odometer implements the api.VehicleOdometer interface -func (v *Provider) Odometer() (float64, error) { - res, err := v.statusG() - if err == nil { - err = api.ErrNotAvailable - - if sd := res.ServiceByID(ServiceOdometer); sd != nil { - if fd := sd.FieldByID(ServiceOdometer); fd != nil { - if val, err := strconv.ParseFloat(fd.Value, 64); err == nil { - return val, nil - } - } - } - } - - return 0, err -} - -var _ api.VehicleClimater = (*Provider)(nil) - -// Climater implements the api.VehicleClimater interface -func (v *Provider) Climater() (bool, error) { - res, err := v.climateG() - if err == nil { - state := strings.ToLower(res.Climater.Status.ClimatisationStatusData.ClimatisationState.Content) - active := state != "off" && state != "invalid" && state != "error" - - return active, nil - } - - return false, err -} - -var _ api.VehiclePosition = (*Provider)(nil) - -// Position implements the api.VehiclePosition interface -func (v *Provider) Position() (float64, float64, error) { - res, err := v.positionG() - if err == nil { - coord := res.FindCarResponse.Position.CarCoordinate - return float64(coord.Latitude) / 1e6, float64(coord.Longitude) / 1e6, nil - } - - return 0, 0, err -} - -var _ api.ChargeController = (*Provider)(nil) - -// ChargeEnable implements the api.ChargeController interface -func (v *Provider) ChargeEnable(enable bool) error { - action := map[bool]string{true: ActionChargeStart, false: ActionChargeStop} - return v.action(ActionCharge, action[enable]) -} - -var _ api.Diagnosis = (*Provider)(nil) - -// Diagnose implements the api.Diagnosis interface -func (v *Provider) Diagnose() { - rr, err := v.rr() - if err != nil { - return - } - - tw := tabwriter.NewWriter(os.Stdout, 0, 0, 1, ' ', 0) - - slices.SortFunc(rr.OperationList.ServiceInfo, func(i, j ServiceInfo) int { - return cmp.Compare(i.ServiceId, j.ServiceId) - }) - - for _, si := range rr.OperationList.ServiceInfo { - if si.InvocationUrl.Content != "" { - fmt.Fprintf(tw, "%s:\t%s\n", si.ServiceId, si.InvocationUrl.Content) - } - } - - // list remaining service - services := lo.FilterMap(rr.OperationList.ServiceInfo, func(si ServiceInfo, _ int) (string, bool) { - return si.ServiceId, si.InvocationUrl.Content == "" - }) - - fmt.Fprintf(tw, "without uri:\t%s\n", strings.Join(services, ",")) - - tw.Flush() -} diff --git a/vehicle/vw/samples/rolesrights_egolf.json b/vehicle/vw/samples/rolesrights_egolf.json deleted file mode 100644 index e003f40ad..000000000 --- a/vehicle/vw/samples/rolesrights_egolf.json +++ /dev/null @@ -1,2009 +0,0 @@ -{ - "operationList": { - "vin": "WVWZZZ...", - "channelClient": "APP", - "userId": "...", - "role": "PRIMARY_USER", - "securityLevel": "HG_3", - "status": "ENABLED", - "vehicleLifeCycleStatus": { - "content": "DELIVERED", - "garage": false - }, - "serviceInfo": [ - { - "serviceId": "dealerappoint_v1", - "serviceType": "mbb", - "serviceStatus": { - "status": "Enabled" - }, - "licenseRequired": true, - "cumulatedLicense": { - "status": "ACTIVATED", - "warn": false, - "activationBy": "ownersVerification", - "activationDate": { - "content": "2019-04-26T14:36:00Z" - }, - "expirationDate": { - "content": "2029-04-26T14:36:00Z" - }, - "licenseProfiles": { - "lastUsedProfile": "LPBundle00000721", - "licenseProfile": [ - { - "content": "LPBundle00000721", - "ltype": "regular", - "profileType": "implicit", - "salesPartNo": "NET.500.011.L", - "duration": "P10Y" - } - ] - } - }, - "primaryUserRequired": true, - "termsAndConditionsRequired": true, - "blockDisabling": false, - "personalized": false, - "configurable": false, - "deviceType": "TELEMATICS", - "serviceEol": "2121-01-11T09:23:27Z", - "privacyGroups": null, - "parameters": null, - "rolesAndRightsRequired": true, - "invocationUrl": { - "content": "https://mal-1a.prd.ece.vwg-connect.com/api/bs/otv/v1/vehicles/{vin}/" - }, - "operation": [ - { - "id": "G_SAPP", - "version": "1", - "permission": "granted", - "requiredUserRole": "PRIMARY_USER", - "requiredSecurityLevel": "HG_1", - "authenticationScope": [ - { - "content": "sc2:fal", - "authLevel": "T2" - } - ] - }, - { - "id": "S_CONFDATA", - "version": "1", - "permission": "granted", - "requiredUserRole": "PRIMARY_USER", - "requiredSecurityLevel": "HG_1", - "authenticationScope": [ - { - "content": "sc2:fal", - "authLevel": "T2" - } - ] - }, - { - "id": "G_CONFDATA", - "version": "1", - "permission": "granted", - "requiredUserRole": "PRIMARY_USER", - "requiredSecurityLevel": "HG_1", - "authenticationScope": [ - { - "content": "sc2:fal", - "authLevel": "T2" - } - ] - } - ] - }, - { - "serviceId": "timerprogramming_v1", - "serviceType": "mbb", - "serviceStatus": { - "status": "Enabled" - }, - "licenseRequired": true, - "cumulatedLicense": { - "status": "ACTIVATED", - "warn": false, - "activationBy": "automatic", - "activationDate": { - "content": "2020-04-30T12:20:00Z" - }, - "expirationDate": { - "content": "2022-04-30T12:20:00Z" - }, - "licenseProfiles": { - "lastUsedProfile": "LPPackage00000244", - "licenseProfile": [ - { - "content": "LPPackage00000244", - "ltype": "regular", - "profileType": "explicit", - "salesPartNo": "NET.500.012.B", - "duration": "P2Y" - }, - { - "content": "LPBundle00000703", - "ltype": "regular", - "profileType": "implicit", - "salesPartNo": "NET.500.012.A", - "duration": "P1Y" - } - ] - } - }, - "primaryUserRequired": true, - "termsAndConditionsRequired": false, - "blockDisabling": false, - "personalized": false, - "configurable": false, - "deviceType": "TELEMATICS", - "serviceEol": "2121-01-11T09:23:27Z", - "privacyGroups": null, - "parameters": { - "parameter": [ - { - "content": true, - "name": "loudpush" - } - ] - }, - "rolesAndRightsRequired": true, - "invocationUrl": { - "content": "https://msg.audi.de/fs-car/bs/departuretimer/v1/{brand}/{country}/vehicles/{vin}/" - }, - "operation": [ - { - "id": "G_PLUG_NOTIFY", - "version": "1", - "permission": "granted", - "requiredUserRole": "SECONDARY_USER", - "requiredSecurityLevel": "HG_1", - "authenticationScope": [ - { - "content": "sc2:fal", - "authLevel": "T2" - } - ] - }, - { - "id": "P_SETTINGS_AU", - "version": "1", - "xsd": "setDepartureTimersAndProfiles_V1_0_2", - "remoteCommand": "setDepartureTimersAndProfiles", - "permission": "granted", - "requiredUserRole": "SECONDARY_USER", - "requiredSecurityLevel": "HG_1", - "parameters": { - "parameter": [ - { - "content": "1", - "name": "auxDisclaimerRequired" - } - ] - }, - "authenticationScope": [ - { - "content": "sc2:fal", - "authLevel": "T2" - } - ] - }, - { - "id": "G_SETTINGS", - "version": "1", - "permission": "granted", - "requiredUserRole": "SECONDARY_USER", - "requiredSecurityLevel": "HG_1", - "authenticationScope": [ - { - "content": "sc2:fal", - "authLevel": "T2" - } - ] - }, - { - "id": "P_PLUG_NOTIFY", - "version": "1", - "permission": "granted", - "requiredUserRole": "SECONDARY_USER", - "requiredSecurityLevel": "HG_1", - "authenticationScope": [ - { - "content": "sc2:fal", - "authLevel": "T2" - } - ] - }, - { - "id": "G_JOBSTATUS", - "version": "1", - "permission": "granted", - "requiredUserRole": "SECONDARY_USER", - "requiredSecurityLevel": "HG_1", - "authenticationScope": [ - { - "content": "sc2:fal", - "authLevel": "T2" - } - ] - }, - { - "id": "G_DATA", - "version": "1", - "permission": "granted", - "requiredUserRole": "SECONDARY_USER", - "requiredSecurityLevel": "HG_1", - "authenticationScope": [ - { - "content": "sc2:fal", - "authLevel": "T2" - } - ] - }, - { - "id": "P_SETTING_CML", - "version": "1", - "xsd": "setDepartureTimeBasicSettingsJob_v1_0_2", - "remoteCommand": "setDepartureTimeBasicSettings", - "permission": "granted", - "requiredUserRole": "SECONDARY_USER", - "requiredSecurityLevel": "HG_1", - "authenticationScope": [ - { - "content": "sc2:fal", - "authLevel": "T2" - } - ] - }, - { - "id": "P_SETTINGS_EL", - "version": "1", - "xsd": "setDepartureTimersAndProfiles_V1_0_2", - "remoteCommand": "setDepartureTimersAndProfiles", - "permission": "granted", - "requiredUserRole": "SECONDARY_USER", - "requiredSecurityLevel": "HG_1", - "authenticationScope": [ - { - "content": "sc2:fal", - "authLevel": "T2" - } - ] - }, - { - "id": "P_REMINDER_NOTIFY", - "version": "1", - "permission": "granted", - "requiredUserRole": "SECONDARY_USER", - "requiredSecurityLevel": "HG_1", - "authenticationScope": [ - { - "content": "sc2:fal", - "authLevel": "T2" - } - ] - }, - { - "id": "G_STATUS", - "version": "1", - "permission": "granted", - "requiredUserRole": "SECONDARY_USER", - "requiredSecurityLevel": "HG_1", - "authenticationScope": [ - { - "content": "sc2:fal", - "authLevel": "T2" - } - ] - }, - { - "id": "G_REMINDER_NOTIFY", - "version": "1", - "permission": "granted", - "requiredUserRole": "SECONDARY_USER", - "requiredSecurityLevel": "HG_1", - "authenticationScope": [ - { - "content": "sc2:fal", - "authLevel": "T2" - } - ] - } - ] - }, - { - "serviceId": "owner_v1", - "serviceType": "mbb", - "serviceStatus": { - "status": "Enabled" - }, - "licenseRequired": false, - "primaryUserRequired": false, - "termsAndConditionsRequired": false, - "blockDisabling": true, - "personalized": false, - "configurable": false, - "deviceType": "INFOTAINMENT", - "serviceEol": "2121-04-24T07:21:36Z", - "privacyGroups": null, - "parameters": { - "parameter": [ - { - "content": true, - "name": "has_wlan" - } - ] - }, - "rolesAndRightsRequired": true, - "operation": [ - { - "id": "P_INITENROLLMENTCODE", - "version": "1", - "permission": "granted", - "requiredUserRole": "GUEST_USER", - "requiredSecurityLevel": "HG_0" - }, - { - "id": "G_ENROLLMENTCODE", - "version": "1", - "permission": "granted", - "requiredUserRole": "GUEST_USER", - "requiredSecurityLevel": "HG_0" - }, - { - "id": "D_VUSERENROLLMENTRESET", - "version": "1", - "permission": "granted", - "requiredUserRole": "PRIMARY_USER", - "requiredSecurityLevel": "HG_1" - }, - { - "id": "G_VENROLLMENTSTATUS", - "version": "1", - "permission": "granted", - "requiredUserRole": "GUEST_USER", - "requiredSecurityLevel": "HG_0" - }, - { - "id": "D_VENROLLMENTRESET", - "version": "1", - "permission": "granted", - "requiredUserRole": "PRIMARY_USER", - "requiredSecurityLevel": "HG_1" - }, - { - "id": "G_VUSERENROLLMENTSTATUS", - "version": "1", - "permission": "granted", - "requiredUserRole": "GUEST_USER", - "requiredSecurityLevel": "HG_0" - } - ] - }, - { - "serviceId": "zieleinspeisung_v2", - "serviceType": "mbb", - "serviceStatus": { - "status": "Enabled" - }, - "licenseRequired": true, - "cumulatedLicense": { - "status": "ACTIVATED", - "warn": false, - "activationBy": "automatic", - "activationDate": { - "content": "2019-04-26T14:36:00Z" - }, - "expirationDate": { - "content": "2022-04-26T14:36:00Z" - }, - "licenseProfiles": { - "lastUsedProfile": "LPPackage00000042", - "licenseProfile": [ - { - "content": "LPPackage00000042", - "ltype": "regular", - "profileType": "explicit", - "salesPartNo": "NET.500.003.B", - "duration": "P2Y" - }, - { - "content": "LPBundle00000142", - "ltype": "regular", - "profileType": "implicit", - "salesPartNo": "NET.500.003.A", - "duration": "P1Y" - } - ] - } - }, - "primaryUserRequired": true, - "termsAndConditionsRequired": false, - "blockDisabling": false, - "personalized": false, - "configurable": false, - "deviceType": "INFOTAINMENT", - "serviceEol": "2121-04-24T07:21:36Z", - "privacyGroups": null, - "parameters": null, - "rolesAndRightsRequired": false - }, - { - "serviceId": "rhonk_v1", - "serviceType": "mbb", - "serviceStatus": { - "status": "Enabled" - }, - "licenseRequired": true, - "cumulatedLicense": { - "status": "ACTIVATED", - "warn": false, - "activationBy": "automatic", - "activationDate": { - "content": "2020-04-30T12:20:00Z" - }, - "expirationDate": { - "content": "2022-04-30T12:20:00Z" - }, - "licenseProfiles": { - "lastUsedProfile": "LPPackage00000244", - "licenseProfile": [ - { - "content": "LPBundle00000703", - "ltype": "regular", - "profileType": "implicit", - "salesPartNo": "NET.500.012.A", - "duration": "P1Y" - }, - { - "content": "LPPackage00000244", - "ltype": "regular", - "profileType": "explicit", - "salesPartNo": "NET.500.012.B", - "duration": "P2Y" - } - ] - } - }, - "primaryUserRequired": true, - "termsAndConditionsRequired": false, - "blockDisabling": false, - "personalized": false, - "configurable": false, - "deviceType": "TELEMATICS", - "serviceEol": "2121-01-11T09:23:27Z", - "privacyGroups": null, - "parameters": null, - "rolesAndRightsRequired": true, - "operation": [ - { - "id": "G_RHIST", - "version": "1", - "invocationUrl": { - "content": "https://mal-1a.prd.ece.vwg-connect.com/bs/rhf/v1/vehicles/{vin}/requestHistoryEntries?offset={offset}&limit={limit}", - "method": "GET" - }, - "permission": "granted", - "requiredUserRole": "SECONDARY_USER", - "requiredSecurityLevel": "HG_1", - "authenticationScope": [ - { - "content": "sc2:fal", - "authLevel": "T2" - } - ] - }, - { - "id": "G_REQSTATUS", - "version": "1", - "permission": "granted", - "requiredUserRole": "SECONDARY_USER", - "requiredSecurityLevel": "HG_1", - "authenticationScope": [ - { - "content": "sc2:fal", - "authLevel": "T2" - } - ] - }, - { - "id": "P_VREQ", - "version": "1", - "xsd": "honkAndFlash_v1_0_0", - "remoteCommand": "activateHonkAndFlash", - "permission": "granted", - "requiredUserRole": "SECONDARY_USER", - "requiredSecurityLevel": "HG_1", - "authenticationScope": [ - { - "content": "sc2:fal", - "authLevel": "T2" - } - ] - } - ] - }, - { - "serviceId": "rlu_v1", - "serviceType": "mbb", - "serviceStatus": { - "status": "Enabled" - }, - "licenseRequired": true, - "cumulatedLicense": { - "status": "ACTIVATED", - "warn": false, - "activationBy": "automatic", - "activationDate": { - "content": "2020-04-30T12:20:00Z" - }, - "expirationDate": { - "content": "2022-04-30T12:20:00Z" - }, - "licenseProfiles": { - "lastUsedProfile": "LPPackage00000244", - "licenseProfile": [ - { - "content": "LPBundle00000703", - "ltype": "regular", - "profileType": "implicit", - "salesPartNo": "NET.500.012.A", - "duration": "P1Y" - }, - { - "content": "LPPackage00000244", - "ltype": "regular", - "profileType": "explicit", - "salesPartNo": "NET.500.012.B", - "duration": "P2Y" - } - ] - } - }, - "primaryUserRequired": true, - "termsAndConditionsRequired": false, - "blockDisabling": false, - "personalized": false, - "configurable": false, - "deviceType": "TELEMATICS", - "serviceEol": "2121-01-11T09:23:27Z", - "privacyGroups": { - "privacyGroup": [ - "personalUser" - ] - }, - "parameters": null, - "rolesAndRightsRequired": true, - "operation": [ - { - "id": "LOCK", - "version": "1", - "invocationUrl": { - "content": "https://mal-1a.prd.ece.vwg-connect.com/api/bs/rlu/v1/vehicles/{vin}/lock", - "method": "POST" - }, - "xsd": "rlu_v1_0_0", - "remoteCommand": "remoteLockJob", - "permission": "granted", - "requiredUserRole": "SECONDARY_USER", - "requiredSecurityLevel": "HG_3", - "extAuth": "SPIN", - "authenticationScope": [ - { - "content": "sc2:fal", - "authLevel": "T2" - } - ] - }, - { - "id": "G_RQSTAT", - "version": "1", - "invocationUrl": { - "content": "https://mal-1a.prd.ece.vwg-connect.com/api/bs/rlu/v1/vehicles/{vin}/requests/{requestId}/status", - "method": "GET" - }, - "permission": "granted", - "requiredUserRole": "SECONDARY_USER", - "requiredSecurityLevel": "HG_3", - "authenticationScope": [ - { - "content": "sc2:fal", - "authLevel": "T2" - } - ] - }, - { - "id": "UNLOCK", - "version": "1", - "xsd": "rlu_v1_0_0", - "remoteCommand": "remoteUnlockJob", - "permission": "granted", - "requiredUserRole": "SECONDARY_USER", - "requiredSecurityLevel": "HG_3", - "extAuth": "SPIN", - "authenticationScope": [ - { - "content": "sc2:fal", - "authLevel": "T2" - } - ] - }, - { - "id": "G_LACT", - "version": "1", - "invocationUrl": { - "content": "https://mal-1a.prd.ece.vwg-connect.com/api/bs/rlu/v1/vehicles/{vin}/actions", - "method": "GET" - }, - "permission": "granted", - "requiredUserRole": "SECONDARY_USER", - "requiredSecurityLevel": "HG_3", - "authenticationScope": [ - { - "content": "sc2:fal", - "authLevel": "T2" - } - ] - } - ] - }, - { - "serviceId": "speedalert_v1", - "serviceType": "mbb", - "serviceStatus": { - "status": "Enabled" - }, - "licenseRequired": true, - "cumulatedLicense": { - "status": "ACTIVATED", - "warn": false, - "activationBy": "automatic", - "activationDate": { - "content": "2020-04-30T12:20:00Z" - }, - "expirationDate": { - "content": "2022-04-30T12:20:00Z" - }, - "licenseProfiles": { - "lastUsedProfile": "LPPackage00000244", - "licenseProfile": [ - { - "content": "LPBundle00000703", - "ltype": "regular", - "profileType": "implicit", - "salesPartNo": "NET.500.012.A", - "duration": "P1Y" - }, - { - "content": "LPPackage00000244", - "ltype": "regular", - "profileType": "explicit", - "salesPartNo": "NET.500.012.B", - "duration": "P2Y" - } - ] - } - }, - "primaryUserRequired": true, - "termsAndConditionsRequired": false, - "blockDisabling": false, - "personalized": false, - "configurable": false, - "deviceType": "TELEMATICS", - "serviceEol": "2121-01-11T09:23:27Z", - "privacyGroups": null, - "parameters": null, - "rolesAndRightsRequired": true, - "operation": [ - { - "id": "P_DLIST", - "version": "1", - "xsd": "speedAlert_v1_0_0", - "remoteCommand": "activateSpeedAlert", - "permission": "granted", - "requiredUserRole": "PRIMARY_USER", - "requiredSecurityLevel": "HG_1", - "authenticationScope": [ - { - "content": "sc2:fal", - "authLevel": "T2" - } - ] - }, - { - "id": "D_ALERTS", - "version": "1", - "permission": "granted", - "requiredUserRole": "PRIMARY_USER", - "requiredSecurityLevel": "HG_1", - "authenticationScope": [ - { - "content": "sc2:fal", - "authLevel": "T2" - } - ] - }, - { - "id": "D_RHIST", - "version": "1", - "permission": "granted", - "requiredUserRole": "PRIMARY_USER", - "requiredSecurityLevel": "HG_1", - "authenticationScope": [ - { - "content": "sc2:fal", - "authLevel": "T2" - } - ] - }, - { - "id": "G_DLIST", - "version": "1", - "permission": "granted", - "requiredUserRole": "PRIMARY_USER", - "requiredSecurityLevel": "HG_1", - "authenticationScope": [ - { - "content": "sc2:fal", - "authLevel": "T2" - } - ] - }, - { - "id": "G_DLSTATUS", - "version": "1", - "permission": "granted", - "requiredUserRole": "PRIMARY_USER", - "requiredSecurityLevel": "HG_1", - "authenticationScope": [ - { - "content": "sc2:fal", - "authLevel": "T2" - } - ] - }, - { - "id": "D_RHENTRY", - "version": "1", - "permission": "granted", - "requiredUserRole": "PRIMARY_USER", - "requiredSecurityLevel": "HG_1", - "authenticationScope": [ - { - "content": "sc2:fal", - "authLevel": "T2" - } - ] - }, - { - "id": "D_ALERT", - "version": "1", - "permission": "granted", - "requiredUserRole": "PRIMARY_USER", - "requiredSecurityLevel": "HG_1", - "authenticationScope": [ - { - "content": "sc2:fal", - "authLevel": "T2" - } - ] - }, - { - "id": "G_CONF", - "version": "1", - "permission": "granted", - "requiredUserRole": "PRIMARY_USER", - "requiredSecurityLevel": "HG_1", - "authenticationScope": [ - { - "content": "sc2:fal", - "authLevel": "T2" - } - ] - }, - { - "id": "G_RHIST", - "version": "1", - "permission": "granted", - "requiredUserRole": "PRIMARY_USER", - "requiredSecurityLevel": "HG_1", - "authenticationScope": [ - { - "content": "sc2:fal", - "authLevel": "T2" - } - ] - }, - { - "id": "G_ALERTS", - "version": "1", - "permission": "granted", - "requiredUserRole": "PRIMARY_USER", - "requiredSecurityLevel": "HG_1", - "authenticationScope": [ - { - "content": "sc2:fal", - "authLevel": "T2" - } - ] - } - ], - "authenticationScope": [ - { - "content": "sc2:fal", - "authLevel": "T2" - } - ] - }, - { - "serviceId": "trip_statistic_v1", - "serviceType": "mbb", - "serviceStatus": { - "status": "Enabled" - }, - "licenseRequired": true, - "cumulatedLicense": { - "status": "ACTIVATED", - "warn": false, - "activationBy": "automatic", - "activationDate": { - "content": "2020-04-30T12:20:00Z" - }, - "expirationDate": { - "content": "2022-04-30T12:20:00Z" - }, - "licenseProfiles": { - "lastUsedProfile": "LPPackage00000244", - "licenseProfile": [ - { - "content": "LPPackage00000244", - "ltype": "regular", - "profileType": "explicit", - "salesPartNo": "NET.500.012.B", - "duration": "P2Y" - }, - { - "content": "LPBundle00000703", - "ltype": "regular", - "profileType": "implicit", - "salesPartNo": "NET.500.012.A", - "duration": "P1Y" - } - ] - } - }, - "primaryUserRequired": true, - "termsAndConditionsRequired": false, - "blockDisabling": false, - "personalized": false, - "configurable": false, - "deviceType": "TELEMATICS", - "serviceEol": "2121-01-11T09:23:27Z", - "privacyGroups": null, - "parameters": { - "parameter": [ - { - "content": false, - "name": "electric_consumption" - }, - { - "content": true, - "name": "triptype_short" - }, - { - "content": false, - "name": "auxiliary_consumption" - }, - { - "content": false, - "name": "fuel_overall_consumption" - }, - { - "content": true, - "name": "triptype_cyclic" - }, - { - "content": true, - "name": "triptype_long" - }, - { - "content": true, - "name": "electric_overall_consumption" - }, - { - "content": false, - "name": "recuperation" - } - ] - }, - "rolesAndRightsRequired": true, - "operation": [ - { - "id": "G_AGGR_TRIPDATA", - "version": "1", - "permission": "granted", - "requiredUserRole": "SECONDARY_USER", - "requiredSecurityLevel": "HG_1" - }, - { - "id": "G_JOBSTATUS", - "version": "1", - "permission": "granted", - "requiredUserRole": "SECONDARY_USER", - "requiredSecurityLevel": "HG_1" - }, - { - "id": "D_TRIPDATA", - "version": "1", - "permission": "granted", - "requiredUserRole": "SECONDARY_USER", - "requiredSecurityLevel": "HG_1" - }, - { - "id": "G_TRIPDATA", - "version": "1", - "permission": "granted", - "requiredUserRole": "SECONDARY_USER", - "requiredSecurityLevel": "HG_1" - } - ] - }, - { - "serviceId": "rclima_v1", - "serviceType": "mbb", - "serviceStatus": { - "status": "Enabled" - }, - "licenseRequired": true, - "cumulatedLicense": { - "status": "ACTIVATED", - "warn": false, - "activationBy": "automatic", - "activationDate": { - "content": "2020-04-30T12:20:00Z" - }, - "expirationDate": { - "content": "2022-04-30T12:20:00Z" - }, - "licenseProfiles": { - "lastUsedProfile": "LPPackage00000244", - "licenseProfile": [ - { - "content": "LPBundle00000703", - "ltype": "regular", - "profileType": "implicit", - "salesPartNo": "NET.500.012.A", - "duration": "P1Y" - }, - { - "content": "LPPackage00000244", - "ltype": "regular", - "profileType": "explicit", - "salesPartNo": "NET.500.012.B", - "duration": "P2Y" - } - ] - } - }, - "primaryUserRequired": true, - "termsAndConditionsRequired": false, - "blockDisabling": false, - "personalized": false, - "configurable": false, - "deviceType": "TELEMATICS", - "serviceEol": "2121-01-11T09:23:27Z", - "privacyGroups": null, - "parameters": { - "parameter": [ - { - "content": true, - "name": "loudpush" - } - ] - }, - "rolesAndRightsRequired": true, - "invocationUrl": { - "content": "https://mal-1a.prd.ece.vwg-connect.com/api/bs/climatisation/v1/vehicles/{vin}/" - }, - "operation": [ - { - "id": "G_DATA", - "version": "1", - "permission": "granted", - "requiredUserRole": "SECONDARY_USER", - "requiredSecurityLevel": "HG_1", - "authenticationScope": [ - { - "content": "sc2:fal", - "authLevel": "T2" - } - ] - }, - { - "id": "P_START_CLIMA_EL", - "version": "1", - "xsd": "startClimatisationJob_v1_0_2", - "remoteCommand": "startClimatisation", - "permission": "granted", - "requiredUserRole": "SECONDARY_USER", - "requiredSecurityLevel": "HG_1", - "authenticationScope": [ - { - "content": "sc2:fal", - "authLevel": "T2" - } - ] - }, - { - "id": "G_SETTINGS", - "version": "1", - "permission": "granted", - "requiredUserRole": "SECONDARY_USER", - "requiredSecurityLevel": "HG_1", - "authenticationScope": [ - { - "content": "sc2:fal", - "authLevel": "T2" - } - ] - }, - { - "id": "G_STATUS", - "version": "1", - "permission": "granted", - "requiredUserRole": "SECONDARY_USER", - "requiredSecurityLevel": "HG_1", - "authenticationScope": [ - { - "content": "sc2:fal", - "authLevel": "T2" - } - ] - }, - { - "id": "P_STOP_WND", - "version": "1", - "xsd": "stopWindowHeatingJob_v1_0_0", - "remoteCommand": "stopWindowHeating", - "permission": "granted", - "requiredUserRole": "SECONDARY_USER", - "requiredSecurityLevel": "HG_1", - "authenticationScope": [ - { - "content": "sc2:fal", - "authLevel": "T2" - } - ] - }, - { - "id": "P_START_CLIMA_NOSET", - "version": "1", - "xsd": "startClimatisationJob_v1_0_2", - "remoteCommand": "startClimatisation", - "permission": "granted", - "requiredUserRole": "SECONDARY_USER", - "requiredSecurityLevel": "HG_1", - "authenticationScope": [ - { - "content": "sc2:fal", - "authLevel": "T2" - } - ] - }, - { - "id": "P_START_WND", - "version": "1", - "xsd": "startWindowHeatingJob_v1_0_2", - "remoteCommand": "startWindowHeating", - "permission": "granted", - "requiredUserRole": "SECONDARY_USER", - "requiredSecurityLevel": "HG_1", - "authenticationScope": [ - { - "content": "sc2:fal", - "authLevel": "T2" - } - ] - }, - { - "id": "P_STOP", - "version": "1", - "xsd": "stopClimatisationJob_v1_0_0", - "remoteCommand": "stopClimatisation", - "permission": "granted", - "requiredUserRole": "SECONDARY_USER", - "requiredSecurityLevel": "HG_1", - "authenticationScope": [ - { - "content": "sc2:fal", - "authLevel": "T2" - } - ] - }, - { - "id": "G_JOBSTATUS", - "version": "1", - "permission": "granted", - "requiredUserRole": "SECONDARY_USER", - "requiredSecurityLevel": "HG_1", - "authenticationScope": [ - { - "content": "sc2:fal", - "authLevel": "T2" - } - ] - }, - { - "id": "P_SETTINGS", - "version": "1", - "xsd": "setClimatisationSettingsJob_v1_0_2", - "remoteCommand": "setClimatisationSettings", - "permission": "granted", - "requiredUserRole": "SECONDARY_USER", - "requiredSecurityLevel": "HG_1", - "authenticationScope": [ - { - "content": "sc2:fal", - "authLevel": "T2" - } - ] - } - ] - }, - { - "serviceId": "geofence_v1", - "serviceType": "mbb", - "serviceStatus": { - "status": "Enabled" - }, - "licenseRequired": true, - "cumulatedLicense": { - "status": "ACTIVATED", - "warn": false, - "activationBy": "automatic", - "activationDate": { - "content": "2020-04-30T12:20:00Z" - }, - "expirationDate": { - "content": "2022-04-30T12:20:00Z" - }, - "licenseProfiles": { - "lastUsedProfile": "LPPackage00000244", - "licenseProfile": [ - { - "content": "LPPackage00000244", - "ltype": "regular", - "profileType": "explicit", - "salesPartNo": "NET.500.012.B", - "duration": "P2Y" - }, - { - "content": "LPBundle00000703", - "ltype": "regular", - "profileType": "implicit", - "salesPartNo": "NET.500.012.A", - "duration": "P1Y" - } - ] - } - }, - "primaryUserRequired": true, - "termsAndConditionsRequired": false, - "blockDisabling": false, - "personalized": false, - "configurable": false, - "deviceType": "TELEMATICS", - "serviceEol": "2121-01-11T09:23:27Z", - "privacyGroups": null, - "parameters": null, - "rolesAndRightsRequired": true, - "operation": [ - { - "id": "D_ALERT", - "version": "1", - "permission": "granted", - "requiredUserRole": "PRIMARY_USER", - "requiredSecurityLevel": "HG_1", - "authenticationScope": [ - { - "content": "sc2:fal", - "authLevel": "T2" - } - ] - }, - { - "id": "P_DLIST", - "version": "1", - "xsd": "geoFencing_v1_0_0", - "remoteCommand": "activateGeoFencing", - "permission": "granted", - "requiredUserRole": "PRIMARY_USER", - "requiredSecurityLevel": "HG_1", - "authenticationScope": [ - { - "content": "sc2:fal", - "authLevel": "T2" - } - ] - }, - { - "id": "D_ALERTS", - "version": "1", - "permission": "granted", - "requiredUserRole": "PRIMARY_USER", - "requiredSecurityLevel": "HG_1", - "authenticationScope": [ - { - "content": "sc2:fal", - "authLevel": "T2" - } - ] - }, - { - "id": "G_ALERTS", - "version": "1", - "permission": "granted", - "requiredUserRole": "PRIMARY_USER", - "requiredSecurityLevel": "HG_1", - "authenticationScope": [ - { - "content": "sc2:fal", - "authLevel": "T2" - } - ] - }, - { - "id": "G_CONF", - "version": "1", - "permission": "granted", - "requiredUserRole": "PRIMARY_USER", - "requiredSecurityLevel": "HG_1", - "authenticationScope": [ - { - "content": "sc2:fal", - "authLevel": "T2" - } - ] - }, - { - "id": "D_RHIST", - "version": "1", - "permission": "granted", - "requiredUserRole": "PRIMARY_USER", - "requiredSecurityLevel": "HG_1", - "authenticationScope": [ - { - "content": "sc2:fal", - "authLevel": "T2" - } - ] - }, - { - "id": "G_DLSTATUS", - "version": "1", - "permission": "granted", - "requiredUserRole": "PRIMARY_USER", - "requiredSecurityLevel": "HG_1", - "authenticationScope": [ - { - "content": "sc2:fal", - "authLevel": "T2" - } - ] - }, - { - "id": "G_DLIST", - "version": "1", - "permission": "granted", - "requiredUserRole": "PRIMARY_USER", - "requiredSecurityLevel": "HG_1", - "authenticationScope": [ - { - "content": "sc2:fal", - "authLevel": "T2" - } - ] - }, - { - "id": "D_RHENTRY", - "version": "1", - "permission": "granted", - "requiredUserRole": "PRIMARY_USER", - "requiredSecurityLevel": "HG_1", - "authenticationScope": [ - { - "content": "sc2:fal", - "authLevel": "T2" - } - ] - }, - { - "id": "G_RHIST", - "version": "1", - "permission": "granted", - "requiredUserRole": "PRIMARY_USER", - "requiredSecurityLevel": "HG_1", - "authenticationScope": [ - { - "content": "sc2:fal", - "authLevel": "T2" - } - ] - } - ], - "authenticationScope": [ - { - "content": "sc2:fal", - "authLevel": "T2" - } - ] - }, - { - "serviceId": "statusreport_v1", - "serviceType": "mbb", - "serviceStatus": { - "status": "Enabled" - }, - "licenseRequired": true, - "cumulatedLicense": { - "status": "ACTIVATED", - "warn": false, - "activationBy": "automatic", - "activationDate": { - "content": "2020-04-30T12:20:00Z" - }, - "expirationDate": { - "content": "2022-04-30T12:20:00Z" - }, - "licenseProfiles": { - "lastUsedProfile": "LPPackage00000244", - "licenseProfile": [ - { - "content": "LPPackage00000244", - "ltype": "regular", - "profileType": "explicit", - "salesPartNo": "NET.500.012.B", - "duration": "P2Y" - }, - { - "content": "LPBundle00000703", - "ltype": "regular", - "profileType": "implicit", - "salesPartNo": "NET.500.012.A", - "duration": "P1Y" - } - ] - } - }, - "primaryUserRequired": true, - "termsAndConditionsRequired": false, - "blockDisabling": false, - "personalized": false, - "configurable": false, - "deviceType": "TELEMATICS", - "serviceEol": "2121-01-11T09:23:27Z", - "privacyGroups": null, - "parameters": { - "parameter": [ - { - "content": "BEV", - "name": "vehicletype" - }, - { - "content": true, - "name": "next_serviceinterval" - }, - { - "content": "4", - "name": "doors" - }, - { - "content": "supported", - "name": "windowstate" - }, - { - "content": false, - "name": "oil_serviceinterval" - } - ] - }, - "rolesAndRightsRequired": true, - "operation": [ - { - "id": "G_SVDATA", - "version": "1", - "permission": "granted", - "requiredUserRole": "SECONDARY_USER", - "requiredSecurityLevel": "HG_1", - "authenticationScope": [ - { - "content": "sc2:fal", - "authLevel": "T2" - } - ] - }, - { - "id": "G_CVDATAID", - "version": "1", - "permission": "granted", - "requiredUserRole": "SECONDARY_USER", - "requiredSecurityLevel": "HG_1", - "authenticationScope": [ - { - "content": "sc2:fal", - "authLevel": "T2" - } - ] - }, - { - "id": "G_RQSTAT", - "version": "1", - "permission": "granted", - "requiredUserRole": "SECONDARY_USER", - "requiredSecurityLevel": "HG_1", - "authenticationScope": [ - { - "content": "sc2:fal", - "authLevel": "T2" - } - ] - }, - { - "id": "G_CVDATA", - "version": "1", - "xsd": "rvsRdk_v1_0_1", - "remoteCommand": "sendVehicleStatus", - "permission": "granted", - "requiredUserRole": "SECONDARY_USER", - "requiredSecurityLevel": "HG_1", - "authenticationScope": [ - { - "content": "sc2:fal", - "authLevel": "T2" - } - ] - } - ] - }, - { - "serviceId": "tourimport_v1", - "serviceType": "mbb", - "serviceStatus": { - "status": "Enabled" - }, - "licenseRequired": true, - "cumulatedLicense": { - "status": "ACTIVATED", - "warn": false, - "activationBy": "automatic", - "activationDate": { - "content": "2019-04-26T14:36:00Z" - }, - "expirationDate": { - "content": "2022-04-26T14:36:00Z" - }, - "licenseProfiles": { - "lastUsedProfile": "LPPackage00000042", - "licenseProfile": [ - { - "content": "LPBundle00000142", - "ltype": "regular", - "profileType": "implicit", - "salesPartNo": "NET.500.003.A", - "duration": "P1Y" - }, - { - "content": "LPPackage00000042", - "ltype": "regular", - "profileType": "explicit", - "salesPartNo": "NET.500.003.B", - "duration": "P2Y" - } - ] - } - }, - "primaryUserRequired": true, - "termsAndConditionsRequired": false, - "blockDisabling": false, - "personalized": false, - "configurable": false, - "deviceType": "INFOTAINMENT", - "serviceEol": "2121-04-24T07:21:36Z", - "privacyGroups": null, - "parameters": null, - "rolesAndRightsRequired": true - }, - { - "serviceId": "incar_enrollment_v1", - "serviceType": "mbb", - "serviceStatus": { - "status": "Enabled" - }, - "licenseRequired": false, - "primaryUserRequired": false, - "termsAndConditionsRequired": false, - "blockDisabling": true, - "personalized": false, - "configurable": false, - "deviceType": "INFOTAINMENT", - "serviceEol": "2121-04-24T07:21:36Z", - "privacyGroups": { - "privacyGroup": [ - "personalUser" - ] - }, - "parameters": null, - "rolesAndRightsRequired": false - }, - { - "serviceId": "cc_breakdown_v2", - "serviceType": "mbb", - "serviceStatus": { - "status": "Enabled" - }, - "licenseRequired": true, - "cumulatedLicense": { - "status": "ACTIVATED", - "warn": false, - "activationBy": "ownersVerification", - "activationDate": { - "content": "2019-04-26T14:36:00Z" - }, - "expirationDate": { - "content": "2029-04-26T14:36:00Z" - }, - "licenseProfiles": { - "lastUsedProfile": "LPBundle00000721", - "licenseProfile": [ - { - "content": "LPBundle00000721", - "ltype": "regular", - "profileType": "implicit", - "salesPartNo": "NET.500.011.L", - "duration": "P10Y" - } - ] - } - }, - "primaryUserRequired": true, - "termsAndConditionsRequired": false, - "blockDisabling": false, - "personalized": false, - "configurable": false, - "deviceType": "TELEMATICS", - "serviceEol": "2121-01-11T09:23:27Z", - "privacyGroups": null, - "parameters": null, - "rolesAndRightsRequired": false - }, - { - "serviceId": "lsd_v1", - "serviceType": "mbbInternal", - "serviceStatus": { - "status": "Enabled" - }, - "licenseRequired": false, - "primaryUserRequired": false, - "termsAndConditionsRequired": false, - "blockDisabling": true, - "personalized": false, - "configurable": false, - "deviceType": "TELEMATICS", - "serviceEol": "2121-01-11T09:23:27Z", - "privacyGroups": null, - "parameters": null, - "rolesAndRightsRequired": false - }, - { - "serviceId": "owner_v1", - "serviceType": "mbb", - "serviceStatus": { - "status": "Enabled" - }, - "licenseRequired": false, - "primaryUserRequired": false, - "termsAndConditionsRequired": false, - "blockDisabling": true, - "personalized": false, - "configurable": false, - "deviceType": "TELEMATICS", - "serviceEol": "2121-01-11T09:23:27Z", - "privacyGroups": null, - "parameters": { - "parameter": [ - { - "content": true, - "name": "has_wlan" - } - ] - }, - "rolesAndRightsRequired": true, - "operation": [ - { - "id": "G_VUSERENROLLMENTSTATUS", - "version": "1", - "permission": "granted", - "requiredUserRole": "GUEST_USER", - "requiredSecurityLevel": "HG_0" - }, - { - "id": "D_VUSERENROLLMENTRESET", - "version": "1", - "permission": "granted", - "requiredUserRole": "PRIMARY_USER", - "requiredSecurityLevel": "HG_1" - }, - { - "id": "P_INITENROLLMENTCODE", - "version": "1", - "permission": "granted", - "requiredUserRole": "GUEST_USER", - "requiredSecurityLevel": "HG_0" - }, - { - "id": "D_VENROLLMENTRESET", - "version": "1", - "permission": "granted", - "requiredUserRole": "PRIMARY_USER", - "requiredSecurityLevel": "HG_1" - }, - { - "id": "G_ENROLLMENTCODE", - "version": "1", - "permission": "granted", - "requiredUserRole": "GUEST_USER", - "requiredSecurityLevel": "HG_0" - }, - { - "id": "G_VENROLLMENTSTATUS", - "version": "1", - "permission": "granted", - "requiredUserRole": "GUEST_USER", - "requiredSecurityLevel": "HG_0" - } - ] - }, - { - "serviceId": "vehiclehealth_v1", - "serviceType": "mbb", - "serviceStatus": { - "status": "Enabled" - }, - "licenseRequired": true, - "cumulatedLicense": { - "status": "ACTIVATED", - "warn": false, - "activationBy": "automatic", - "activationDate": { - "content": "2019-04-26T14:36:00Z" - }, - "expirationDate": { - "content": "2029-04-26T14:36:00Z" - }, - "licenseProfiles": { - "lastUsedProfile": "LPPackage00000042", - "licenseProfile": [ - { - "content": "LPBundle00000721", - "ltype": "regular", - "profileType": "implicit", - "salesPartNo": "NET.500.011.L", - "duration": "P10Y" - }, - { - "content": "LPPackage00000042", - "ltype": "regular", - "profileType": "explicit", - "salesPartNo": "NET.500.003.B", - "duration": "P2Y" - } - ] - } - }, - "primaryUserRequired": true, - "termsAndConditionsRequired": false, - "blockDisabling": false, - "personalized": false, - "configurable": false, - "deviceType": "TELEMATICS", - "serviceEol": "2121-01-11T09:23:27Z", - "privacyGroups": null, - "parameters": null, - "rolesAndRightsRequired": true, - "operation": [ - { - "id": "G_VHRLIMIT", - "version": "1", - "permission": "granted", - "requiredUserRole": "SECONDARY_USER", - "requiredSecurityLevel": "HG_1", - "authenticationScope": [ - { - "content": "sc2:fal", - "authLevel": "T2" - } - ] - }, - { - "id": "P_IVHR", - "version": "1", - "xsd": "requestVehicleHealthReport_v1_0_1", - "remoteCommand": "requestVehicleHealthReport", - "permission": "granted", - "requiredUserRole": "SECONDARY_USER", - "requiredSecurityLevel": "HG_1", - "authenticationScope": [ - { - "content": "sc2:fal", - "authLevel": "T2" - } - ] - } - ] - }, - { - "serviceId": "carfinder_v1", - "serviceType": "mbb", - "serviceStatus": { - "status": "Enabled" - }, - "licenseRequired": true, - "cumulatedLicense": { - "status": "ACTIVATED", - "warn": false, - "activationBy": "automatic", - "activationDate": { - "content": "2020-04-30T12:20:00Z" - }, - "expirationDate": { - "content": "2022-04-30T12:20:00Z" - }, - "licenseProfiles": { - "lastUsedProfile": "LPPackage00000244", - "licenseProfile": [ - { - "content": "LPPackage00000244", - "ltype": "regular", - "profileType": "explicit", - "salesPartNo": "NET.500.012.B", - "duration": "P2Y" - }, - { - "content": "LPBundle00000703", - "ltype": "regular", - "profileType": "implicit", - "salesPartNo": "NET.500.012.A", - "duration": "P1Y" - } - ] - } - }, - "primaryUserRequired": true, - "termsAndConditionsRequired": false, - "blockDisabling": false, - "personalized": false, - "configurable": false, - "deviceType": "TELEMATICS", - "serviceEol": "2121-01-11T09:23:27Z", - "privacyGroups": null, - "parameters": null, - "rolesAndRightsRequired": true, - "operation": [ - { - "id": "FIND_CAR", - "version": "1", - "invocationUrl": { - "content": "https://mal-1a.prd.ece.vwg-connect.com/bs/cf/vehicles/{vin}/position", - "method": "GET" - }, - "permission": "granted", - "requiredUserRole": "SECONDARY_USER", - "requiredSecurityLevel": "HG_1", - "authenticationScope": [ - { - "content": "sc2:fal", - "authLevel": "T2" - } - ] - } - ] - }, - { - "serviceId": "rbatterycharge_v1", - "serviceType": "mbb", - "serviceStatus": { - "status": "Enabled" - }, - "licenseRequired": true, - "cumulatedLicense": { - "status": "ACTIVATED", - "warn": false, - "activationBy": "automatic", - "activationDate": { - "content": "2020-04-30T12:20:00Z" - }, - "expirationDate": { - "content": "2022-04-30T12:20:00Z" - }, - "licenseProfiles": { - "lastUsedProfile": "LPPackage00000244", - "licenseProfile": [ - { - "content": "LPPackage00000244", - "ltype": "regular", - "profileType": "explicit", - "salesPartNo": "NET.500.012.B", - "duration": "P2Y" - }, - { - "content": "LPBundle00000703", - "ltype": "regular", - "profileType": "implicit", - "salesPartNo": "NET.500.012.A", - "duration": "P1Y" - } - ] - } - }, - "primaryUserRequired": true, - "termsAndConditionsRequired": false, - "blockDisabling": false, - "personalized": false, - "configurable": false, - "deviceType": "TELEMATICS", - "serviceEol": "2121-01-11T09:23:27Z", - "privacyGroups": null, - "parameters": { - "parameter": [ - { - "content": true, - "name": "loudpush" - }, - { - "content": "32", - "name": "max_current" - } - ] - }, - "rolesAndRightsRequired": true, - "invocationUrl": { - "content": "https://msg.audi.de/fs-car/bs/batterycharge/v1/{brand}/{country}/vehicles/{vin}/" - }, - "operation": [ - { - "id": "P_START", - "version": "1", - "xsd": "startBatteryChargingJob_v1_0_1", - "remoteCommand": "startBatteryCharging", - "permission": "granted", - "requiredUserRole": "SECONDARY_USER", - "requiredSecurityLevel": "HG_1", - "authenticationScope": [ - { - "content": "sc2:fal", - "authLevel": "T2" - } - ] - }, - { - "id": "P_SETTINGS", - "version": "1", - "xsd": "setBatteryChargingSettingsJob_v1_0_1", - "remoteCommand": "setBatteryChargingSettings", - "permission": "granted", - "requiredUserRole": "SECONDARY_USER", - "requiredSecurityLevel": "HG_1", - "authenticationScope": [ - { - "content": "sc2:fal", - "authLevel": "T2" - } - ] - }, - { - "id": "G_SETTINGS", - "version": "1", - "permission": "granted", - "requiredUserRole": "SECONDARY_USER", - "requiredSecurityLevel": "HG_1", - "authenticationScope": [ - { - "content": "sc2:fal", - "authLevel": "T2" - } - ] - }, - { - "id": "G_STATUS", - "version": "1", - "permission": "granted", - "requiredUserRole": "SECONDARY_USER", - "requiredSecurityLevel": "HG_1", - "authenticationScope": [ - { - "content": "sc2:fal", - "authLevel": "T2" - } - ] - }, - { - "id": "G_DATA", - "version": "1", - "permission": "granted", - "requiredUserRole": "SECONDARY_USER", - "requiredSecurityLevel": "HG_1", - "authenticationScope": [ - { - "content": "sc2:fal", - "authLevel": "T2" - } - ] - }, - { - "id": "G_JOBSTATUS", - "version": "1", - "permission": "granted", - "requiredUserRole": "SECONDARY_USER", - "requiredSecurityLevel": "HG_1", - "authenticationScope": [ - { - "content": "sc2:fal", - "authLevel": "T2" - } - ] - }, - { - "id": "P_STOP", - "version": "1", - "xsd": "stopBatteryChargingJob_v1_0_0", - "remoteCommand": "stopBatteryCharging", - "permission": "granted", - "requiredUserRole": "SECONDARY_USER", - "requiredSecurityLevel": "HG_1", - "authenticationScope": [ - { - "content": "sc2:fal", - "authLevel": "T2" - } - ] - }, - { - "id": "P_START_NOSET", - "version": "1", - "xsd": "startBatteryChargingJob_v1_0_1", - "remoteCommand": "startBatteryCharging", - "permission": "granted", - "requiredUserRole": "SECONDARY_USER", - "requiredSecurityLevel": "HG_1", - "authenticationScope": [ - { - "content": "sc2:fal", - "authLevel": "T2" - } - ] - } - ] - }, - { - "serviceId": "lsd_v1", - "serviceType": "mbbInternal", - "serviceStatus": { - "status": "Enabled" - }, - "licenseRequired": false, - "primaryUserRequired": false, - "termsAndConditionsRequired": false, - "blockDisabling": true, - "personalized": false, - "configurable": false, - "deviceType": "INFOTAINMENT", - "serviceEol": "2121-04-24T07:21:36Z", - "privacyGroups": null, - "parameters": null, - "rolesAndRightsRequired": false - } - ] - } -} diff --git a/vehicle/vw/samples/rolesrights_q55.json b/vehicle/vw/samples/rolesrights_q55.json deleted file mode 100644 index 2e0e7ceee..000000000 --- a/vehicle/vw/samples/rolesrights_q55.json +++ /dev/null @@ -1,2001 +0,0 @@ -{ - "operationList": { - "vin": "WAUZZZ...", - "channelClient": "APP", - "userId": "...", - "role": "PRIMARY_USER", - "securityLevel": "HG_2c", - "status": "ENABLED", - "vehicleLifeCycleStatus": { - "content": "DELIVERED", - "garage": false - }, - "serviceInfo": [ - { - "serviceId": "rolesrights_permissions_v1", - "serviceType": "mbb", - "serviceStatus": { - "status": "Enabled" - }, - "licenseRequired": false, - "primaryUserRequired": false, - "termsAndConditionsRequired": false, - "blockDisabling": false, - "personalized": false, - "configurable": false, - "deviceType": "OTHER", - "serviceEol": "2121-09-01T10:17:43Z", - "privacyGroups": null, - "parameters": null, - "rolesAndRightsRequired": false, - "invocationUrl": { - "content": "https://mal-1a.prd.ece.vwg-connect.com/api/rolesrights/permissions/v1/users/{userId}/" - }, - "operation": [ - { - "id": "fetchRole", - "version": "1", - "invocationUrl": { - "content": "https://mal-1a.prd.ece.vwg-connect.com/api/rolesrights/permissions/v1/vehicles/{vin}/users/{userId}/", - "method": "GET" - }, - "permission": "granted", - "requiredUserRole": "GUEST_USER", - "requiredSecurityLevel": "HG_0" - } - ] - }, - { - "serviceId": "zieleinspeisung_v1", - "serviceType": "mbb", - "serviceStatus": { - "status": "Enabled" - }, - "licenseRequired": true, - "cumulatedLicense": { - "status": "ACTIVATED", - "warn": false, - "activationBy": "automatic", - "activationDate": { - "content": "2019-11-29T00:00:00Z" - }, - "expirationDate": { - "content": "2022-11-29T00:00:00Z" - }, - "licenseProfiles": { - "lastUsedProfile": "LPBundle00000423", - "licenseProfile": [ - { - "content": "LPBundle00000423", - "ltype": "regular", - "profileType": "implicit", - "duration": "P3Y" - } - ] - } - }, - "primaryUserRequired": false, - "termsAndConditionsRequired": false, - "blockDisabling": false, - "personalized": false, - "configurable": false, - "deviceType": "INFOTAINMENT", - "serviceEol": "2121-08-30T14:06:06Z", - "privacyGroups": { - "privacyGroup": [ - "personalUser" - ] - }, - "parameters": null, - "rolesAndRightsRequired": true, - "invocationUrl": { - "content": "https://msg.audi.de/fs-car/destinationfeedservice/mydestinations/v1/{brand}/{country}/vehicles/{vin}/users/{userId}/" - }, - "authenticationScope": [ - { - "content": "sc2:fal", - "authLevel": "T2" - } - ] - }, - { - "serviceId": "carfinder_v1", - "serviceType": "mbb", - "serviceStatus": { - "status": "Enabled" - }, - "licenseRequired": true, - "cumulatedLicense": { - "status": "ACTIVATED", - "warn": false, - "activationBy": "automatic", - "activationDate": { - "content": "2019-11-29T00:00:00Z" - }, - "expirationDate": { - "content": "2029-11-29T00:00:00Z" - }, - "licenseProfiles": { - "lastUsedProfile": "LPBundle00000026", - "licenseProfile": [ - { - "content": "LPBundle00000026", - "ltype": "regular", - "profileType": "implicit", - "salesPartNo": "AU736Q7NFPHEVECE3", - "duration": "P10Y" - } - ] - } - }, - "primaryUserRequired": true, - "termsAndConditionsRequired": false, - "blockDisabling": false, - "personalized": false, - "configurable": false, - "deviceType": "TELEMATICS", - "serviceEol": "2120-08-31T13:50:52Z", - "privacyGroups": { - "privacyGroup": [ - "personalGps" - ] - }, - "parameters": null, - "rolesAndRightsRequired": true, - "invocationUrl": { - "content": "https://mal-1a.prd.ece.vwg-connect.com/api/bs/cf/v1/vehicles/{vin}/" - }, - "operation": [ - { - "id": "FIND_CAR", - "version": "1", - "permission": "granted", - "requiredUserRole": "SECONDARY_USER", - "requiredSecurityLevel": "HG_2b", - "authenticationScope": [ - { - "content": "sc2:fal", - "authLevel": "T2" - } - ] - } - ], - "authenticationScope": [ - { - "content": "sc2:fal", - "authLevel": "T2" - } - ] - }, - { - "serviceId": "app_amazonmusic_v1", - "serviceType": "app", - "serviceStatus": { - "status": "Enabled" - }, - "licenseRequired": false, - "primaryUserRequired": false, - "termsAndConditionsRequired": false, - "blockDisabling": false, - "personalized": false, - "configurable": false, - "deviceType": "INFOTAINMENT", - "serviceEol": "2121-08-30T14:06:06Z", - "privacyGroups": { - "privacyGroup": [ - "dormantService" - ] - }, - "parameters": null, - "rolesAndRightsRequired": false - }, - { - "serviceId": "statusreport_v1", - "serviceType": "mbb", - "serviceStatus": { - "status": "Enabled" - }, - "licenseRequired": true, - "cumulatedLicense": { - "status": "ACTIVATED", - "warn": false, - "activationBy": "automatic", - "activationDate": { - "content": "2019-11-29T00:00:00Z" - }, - "expirationDate": { - "content": "2029-11-29T00:00:00Z" - }, - "licenseProfiles": { - "lastUsedProfile": "LPBundle00000066", - "licenseProfile": [ - { - "content": "LPBundle00000066", - "ltype": "regular", - "profileType": "implicit", - "salesPartNo": "AU736Q7NFPHEVECE2", - "duration": "P10Y" - } - ] - } - }, - "primaryUserRequired": true, - "termsAndConditionsRequired": false, - "blockDisabling": false, - "personalized": false, - "configurable": false, - "deviceType": "TELEMATICS", - "serviceEol": "2120-08-31T13:50:52Z", - "privacyGroups": { - "privacyGroup": [ - "personalUser" - ] - }, - "parameters": null, - "rolesAndRightsRequired": true, - "invocationUrl": { - "content": "https://mal-1a.prd.ece.vwg-connect.com/api/bs/vsr/v1/vehicles/{vin}/" - }, - "operation": [ - { - "id": "G_SVDATA", - "version": "1", - "permission": "granted", - "requiredUserRole": "SECONDARY_USER", - "requiredSecurityLevel": "HG_2b", - "authenticationScope": [ - { - "content": "sc2:fal", - "authLevel": "T2" - } - ] - }, - { - "id": "G_CVDATAID", - "version": "1", - "permission": "granted", - "requiredUserRole": "SECONDARY_USER", - "requiredSecurityLevel": "HG_2b", - "authenticationScope": [ - { - "content": "sc2:fal", - "authLevel": "T2" - } - ] - }, - { - "id": "G_RQSTAT", - "version": "1", - "permission": "granted", - "requiredUserRole": "SECONDARY_USER", - "requiredSecurityLevel": "HG_2b", - "authenticationScope": [ - { - "content": "sc2:fal", - "authLevel": "T2" - } - ] - }, - { - "id": "G_CVDATA", - "version": "1", - "xsd": "rvsRdk_v1_0_2", - "remoteCommand": "sendVehicleStatus", - "permission": "granted", - "requiredUserRole": "SECONDARY_USER", - "requiredSecurityLevel": "HG_2b", - "authenticationScope": [ - { - "content": "sc2:fal", - "authLevel": "T2" - } - ] - } - ], - "authenticationScope": [ - { - "content": "sc2:fal", - "authLevel": "T2" - } - ] - }, - { - "serviceId": "rolesrights_securitypin_v2", - "serviceType": "mbb", - "serviceStatus": { - "status": "Enabled" - }, - "licenseRequired": false, - "primaryUserRequired": false, - "termsAndConditionsRequired": false, - "blockDisabling": false, - "personalized": false, - "configurable": false, - "deviceType": "OTHER", - "serviceEol": "2121-09-01T10:17:43Z", - "privacyGroups": null, - "parameters": null, - "rolesAndRightsRequired": false, - "invocationUrl": { - "content": "https://mal-1a.prd.ece.vwg-connect.com/api/rolesrights/securitypin/v2/users/{userId}/" - }, - "operation": [ - { - "id": "prepareSecurityPinTransmission", - "version": "1", - "invocationUrl": { - "content": "https://mal-1a.prd.ece.vwg-connect.com/api/rolesrights/securitypin/v2/users/{userId}/", - "method": "PUT" - }, - "permission": "granted", - "requiredUserRole": "GUEST_USER", - "requiredSecurityLevel": "HG_0" - } - ] - }, - { - "serviceId": "traffic-online_v1", - "serviceType": "mbb", - "serviceStatus": { - "status": "Enabled" - }, - "licenseRequired": true, - "cumulatedLicense": { - "status": "ACTIVATED", - "warn": false, - "activationBy": "automatic", - "activationDate": { - "content": "2019-11-29T00:00:00Z" - }, - "expirationDate": { - "content": "2022-11-29T00:00:00Z" - }, - "licenseProfiles": { - "lastUsedProfile": "LPBundle00000423", - "licenseProfile": [ - { - "content": "LPBundle00000423", - "ltype": "regular", - "profileType": "implicit", - "duration": "P3Y" - } - ] - } - }, - "primaryUserRequired": false, - "termsAndConditionsRequired": false, - "blockDisabling": false, - "personalized": false, - "configurable": false, - "deviceType": "INFOTAINMENT", - "serviceEol": "2121-08-30T14:06:06Z", - "privacyGroups": null, - "parameters": null, - "rolesAndRightsRequired": false - }, - { - "serviceId": "vehicleusers_v1", - "serviceType": "mbb", - "serviceStatus": { - "status": "Enabled" - }, - "licenseRequired": false, - "primaryUserRequired": false, - "termsAndConditionsRequired": false, - "blockDisabling": true, - "personalized": false, - "configurable": false, - "deviceType": "TELEMATICS", - "serviceEol": "2120-08-31T13:50:52Z", - "privacyGroups": { - "privacyGroup": [ - "personalUser" - ] - }, - "parameters": null, - "rolesAndRightsRequired": false - }, - { - "serviceId": "users_v3", - "serviceType": "mbb", - "serviceStatus": { - "status": "Enabled" - }, - "licenseRequired": false, - "primaryUserRequired": false, - "termsAndConditionsRequired": false, - "blockDisabling": false, - "personalized": false, - "configurable": false, - "deviceType": "INFOTAINMENT", - "serviceEol": "2121-08-30T14:06:06Z", - "privacyGroups": null, - "parameters": null, - "rolesAndRightsRequired": false - }, - { - "serviceId": "app_audishop_v1", - "serviceType": "app", - "serviceStatus": { - "status": "Enabled" - }, - "licenseRequired": false, - "primaryUserRequired": false, - "termsAndConditionsRequired": false, - "blockDisabling": false, - "personalized": false, - "configurable": false, - "deviceType": "TELEMATICS", - "serviceEol": "2120-08-31T13:50:52Z", - "privacyGroups": { - "privacyGroup": [ - "dormantService" - ] - }, - "parameters": null, - "rolesAndRightsRequired": false - }, - { - "serviceId": "rlu_v1", - "serviceType": "mbb", - "serviceStatus": { - "status": "Enabled" - }, - "licenseRequired": true, - "cumulatedLicense": { - "status": "ACTIVATED", - "warn": false, - "activationBy": "automatic", - "activationDate": { - "content": "2019-11-29T00:00:00Z" - }, - "expirationDate": { - "content": "2029-11-29T00:00:00Z" - }, - "licenseProfiles": { - "lastUsedProfile": "LPBundle00000026", - "licenseProfile": [ - { - "content": "LPBundle00000026", - "ltype": "regular", - "profileType": "implicit", - "salesPartNo": "AU736Q7NFPHEVECE3", - "duration": "P10Y" - } - ] - } - }, - "primaryUserRequired": true, - "termsAndConditionsRequired": false, - "blockDisabling": false, - "personalized": false, - "configurable": false, - "deviceType": "TELEMATICS", - "serviceEol": "2120-08-31T13:50:52Z", - "privacyGroups": { - "privacyGroup": [ - "personalUser" - ] - }, - "parameters": { - "parameter": [ - { - "content": "1", - "name": "rsdAlwaysOn" - } - ] - }, - "rolesAndRightsRequired": true, - "invocationUrl": { - "content": "https://msg.audi.de/fs-car/bs/rlu/v1/{brand}/{country}/vehicles/{vin}/" - }, - "operation": [ - { - "id": "G_RQSTAT", - "version": "1", - "permission": "granted", - "requiredUserRole": "SECONDARY_USER", - "requiredSecurityLevel": "HG_2b", - "authenticationScope": [ - { - "content": "sc2:fal", - "authLevel": "T2" - } - ] - }, - { - "id": "UNLOCK", - "version": "1", - "permission": "granted", - "requiredUserRole": "SECONDARY_USER", - "requiredSecurityLevel": "HG_2b", - "extAuth": "SPIN", - "authenticationScope": [ - { - "content": "sc2:fal", - "authLevel": "T2" - } - ] - }, - { - "id": "G_LACT", - "version": "1", - "permission": "granted", - "requiredUserRole": "SECONDARY_USER", - "requiredSecurityLevel": "HG_2b", - "authenticationScope": [ - { - "content": "sc2:fal", - "authLevel": "T2" - } - ] - }, - { - "id": "LOCK", - "version": "1", - "permission": "granted", - "requiredUserRole": "SECONDARY_USER", - "requiredSecurityLevel": "HG_2b", - "extAuth": "SPIN", - "authenticationScope": [ - { - "content": "sc2:fal", - "authLevel": "T2" - } - ] - } - ], - "authenticationScope": [ - { - "content": "sc2:fal", - "authLevel": "T2" - } - ] - }, - { - "serviceId": "news_v3", - "serviceType": "mbb", - "serviceStatus": { - "status": "Enabled" - }, - "licenseRequired": true, - "cumulatedLicense": { - "status": "ACTIVATED", - "warn": false, - "activationBy": "automatic", - "activationDate": { - "content": "2019-11-29T00:00:00Z" - }, - "expirationDate": { - "content": "2022-11-29T00:00:00Z" - }, - "licenseProfiles": { - "lastUsedProfile": "LPBundle00000423", - "licenseProfile": [ - { - "content": "LPBundle00000423", - "ltype": "regular", - "profileType": "implicit", - "duration": "P3Y" - } - ] - } - }, - "primaryUserRequired": false, - "termsAndConditionsRequired": false, - "blockDisabling": false, - "personalized": false, - "configurable": true, - "deviceType": "INFOTAINMENT", - "serviceEol": "2121-08-30T14:06:06Z", - "privacyGroups": null, - "parameters": null, - "rolesAndRightsRequired": false, - "invocationUrl": { - "content": "https://mal-1a.prd.ece.vwg-connect.com/api/news/myfeeds/v1/vehicles/{vin}/users/{userId}/" - } - }, - { - "serviceId": "rolesrights_authorization_v2", - "serviceType": "mbb", - "serviceStatus": { - "status": "Enabled" - }, - "licenseRequired": false, - "primaryUserRequired": false, - "termsAndConditionsRequired": false, - "blockDisabling": false, - "personalized": false, - "configurable": false, - "deviceType": "OTHER", - "serviceEol": "2121-09-01T10:17:43Z", - "privacyGroups": null, - "parameters": null, - "rolesAndRightsRequired": false, - "invocationUrl": { - "content": "https://mal-1a.prd.ece.vwg-connect.com/api/rolesrights/authorization/v2/vehicles/{vin}/" - }, - "operation": [ - { - "id": "completeExtAuthV100", - "version": "1", - "invocationUrl": { - "content": "https://msg.audi.de/fs-car/rolesrights/authorization/v2/{brand}/{country}/", - "method": "POST" - }, - "permission": "granted", - "requiredUserRole": "GUEST_USER", - "requiredSecurityLevel": "HG_0" - }, - { - "id": "completeExtAuthV200", - "version": "1", - "invocationUrl": { - "content": "https://mal-1a.prd.ece.vwg-connect.com/api/rolesrights/authorization/v2/", - "method": "POST" - }, - "permission": "granted", - "requiredUserRole": "GUEST_USER", - "requiredSecurityLevel": "HG_0" - }, - { - "id": "requestExtAuthV100", - "version": "1", - "invocationUrl": { - "content": "https://msg.audi.de/fs-car/rolesrights/authorization/v2/{brand}/{country}/vehicles/{vin}/", - "method": "GET" - }, - "permission": "granted", - "requiredUserRole": "GUEST_USER", - "requiredSecurityLevel": "HG_0" - }, - { - "id": "requestExtAuthV200", - "version": "1", - "permission": "granted", - "requiredUserRole": "GUEST_USER", - "requiredSecurityLevel": "HG_0" - }, - { - "id": "initVTAN", - "version": "1", - "permission": "granted", - "requiredUserRole": "GUEST_USER", - "requiredSecurityLevel": "HG_0" - } - ] - }, - { - "serviceId": "travelguide_v1", - "serviceType": "app", - "serviceStatus": { - "status": "Enabled" - }, - "licenseRequired": false, - "primaryUserRequired": false, - "termsAndConditionsRequired": false, - "blockDisabling": false, - "personalized": false, - "configurable": false, - "deviceType": "INFOTAINMENT", - "serviceEol": "2121-08-30T14:06:06Z", - "privacyGroups": null, - "parameters": null, - "rolesAndRightsRequired": false - }, - { - "serviceId": "dealerappoint_v1", - "serviceType": "mbb", - "serviceStatus": { - "status": "Disabled", - "reason": [ - "initiallyDisabled" - ] - }, - "licenseRequired": true, - "cumulatedLicense": { - "status": "ACTIVATED", - "warn": false, - "activationBy": "automatic", - "activationDate": { - "content": "2019-11-29T00:00:00Z" - }, - "expirationDate": { - "content": "2029-11-29T00:00:00Z" - }, - "licenseProfiles": { - "lastUsedProfile": "LPBundle00000027", - "licenseProfile": [ - { - "content": "LPBundle00000027", - "ltype": "regular", - "profileType": "implicit", - "salesPartNo": "AU736Q7NFPHEVECE4", - "duration": "P10Y" - } - ] - } - }, - "primaryUserRequired": true, - "termsAndConditionsRequired": false, - "blockDisabling": false, - "personalized": false, - "configurable": true, - "deviceType": "TELEMATICS", - "serviceEol": "2120-08-31T13:50:52Z", - "privacyGroups": { - "privacyGroup": [ - "personalUser" - ] - }, - "parameters": null, - "rolesAndRightsRequired": true, - "invocationUrl": { - "content": "https://mal-1a.prd.ece.vwg-connect.com/api/bs/otv/v1/vehicles/{vin}/" - }, - "operation": [ - { - "id": "G_CONFDATA", - "version": "1", - "permission": "granted", - "requiredUserRole": "PRIMARY_USER", - "requiredSecurityLevel": "HG_2b", - "authenticationScope": [ - { - "content": "sc2:fal", - "authLevel": "T2" - } - ] - }, - { - "id": "ADM_SWITCH_ON", - "version": "1", - "permission": "granted", - "requiredUserRole": "PRIMARY_USER", - "requiredSecurityLevel": "HG_2b", - "authenticationScope": [ - { - "content": "sc2:fal", - "authLevel": "T2" - } - ] - }, - { - "id": "G_SAPP", - "version": "1", - "permission": "granted", - "requiredUserRole": "PRIMARY_USER", - "requiredSecurityLevel": "HG_2b", - "authenticationScope": [ - { - "content": "sc2:fal", - "authLevel": "T2" - } - ] - }, - { - "id": "S_CONFDATA", - "version": "1", - "permission": "granted", - "requiredUserRole": "PRIMARY_USER", - "requiredSecurityLevel": "HG_2b", - "authenticationScope": [ - { - "content": "sc2:fal", - "authLevel": "T2" - } - ] - }, - { - "id": "ADM_SWITCH_OFF", - "version": "1", - "permission": "granted", - "requiredUserRole": "PRIMARY_USER", - "requiredSecurityLevel": "HG_2b", - "authenticationScope": [ - { - "content": "sc2:fal", - "authLevel": "T2" - } - ] - }, - { - "id": "G_HIST", - "version": "1", - "permission": "granted", - "requiredUserRole": "PRIMARY_USER", - "requiredSecurityLevel": "HG_2b", - "authenticationScope": [ - { - "content": "sc2:fal", - "authLevel": "T2" - } - ] - } - ], - "authenticationScope": [ - { - "content": "sc2:fal", - "authLevel": "T2" - } - ] - }, - { - "serviceId": "cc_breakdown_v2", - "serviceType": "mbb", - "serviceStatus": { - "status": "Enabled" - }, - "licenseRequired": true, - "cumulatedLicense": { - "status": "ACTIVATED", - "warn": false, - "activationBy": "automatic", - "activationDate": { - "content": "2019-11-29T00:00:00Z" - }, - "expirationDate": { - "content": "2029-11-29T00:00:00Z" - }, - "licenseProfiles": { - "lastUsedProfile": "LPBundle00000027", - "licenseProfile": [ - { - "content": "LPBundle00000027", - "ltype": "regular", - "profileType": "implicit", - "salesPartNo": "AU736Q7NFPHEVECE4", - "duration": "P10Y" - } - ] - } - }, - "primaryUserRequired": false, - "termsAndConditionsRequired": false, - "blockDisabling": false, - "personalized": false, - "configurable": false, - "deviceType": "TELEMATICS", - "serviceEol": "2120-08-31T13:50:52Z", - "privacyGroups": { - "privacyGroup": [ - "personalGps", - "personalUser", - "dormantService" - ] - }, - "parameters": null, - "rolesAndRightsRequired": false, - "invocationUrl": { - "content": "https://mal-1a.prd.ece.vwg-connect.com/api/bs/opr/v1/vehicles/{vin}/" - }, - "authenticationScope": [ - { - "content": "sc2:fal", - "authLevel": "T2" - } - ] - }, - { - "serviceId": "rbatterycharge_v1", - "serviceType": "mbb", - "serviceStatus": { - "status": "Enabled" - }, - "licenseRequired": true, - "cumulatedLicense": { - "status": "ACTIVATED", - "warn": false, - "activationBy": "automatic", - "activationDate": { - "content": "2019-11-29T00:00:00Z" - }, - "expirationDate": { - "content": "2029-11-29T00:00:00Z" - }, - "licenseProfiles": { - "lastUsedProfile": "LPBundle00000066", - "licenseProfile": [ - { - "content": "LPBundle00000066", - "ltype": "regular", - "profileType": "implicit", - "salesPartNo": "AU736Q7NFPHEVECE2", - "duration": "P10Y" - } - ] - } - }, - "primaryUserRequired": true, - "termsAndConditionsRequired": false, - "blockDisabling": false, - "personalized": false, - "configurable": false, - "deviceType": "TELEMATICS", - "serviceEol": "2120-08-31T13:50:52Z", - "privacyGroups": { - "privacyGroup": [ - "personalUser" - ] - }, - "parameters": null, - "rolesAndRightsRequired": true, - "invocationUrl": { - "content": "https://msg.audi.de/fs-car/bs/batterycharge/v1/{brand}/{country}/vehicles/{vin}/" - }, - "operation": [ - { - "id": "G_DATA", - "version": "1", - "permission": "granted", - "requiredUserRole": "SECONDARY_USER", - "requiredSecurityLevel": "HG_2b", - "authenticationScope": [ - { - "content": "sc2:fal", - "authLevel": "T2" - } - ] - }, - { - "id": "P_RESET", - "version": "1", - "xsd": "resetRemoteBatteryChargingToDefaultJob_v1_0_0", - "remoteCommand": "resetRemoteBatteryChargingToDefault", - "permission": "granted", - "requiredUserRole": "SECONDARY_USER", - "requiredSecurityLevel": "HG_2b", - "authenticationScope": [ - { - "content": "sc2:fal", - "authLevel": "T2" - } - ] - }, - { - "id": "G_STATUS", - "version": "1", - "permission": "granted", - "requiredUserRole": "SECONDARY_USER", - "requiredSecurityLevel": "HG_2b", - "authenticationScope": [ - { - "content": "sc2:fal", - "authLevel": "T2" - } - ] - }, - { - "id": "P_START_NOSET", - "version": "1", - "xsd": "startBatteryChargingJob_v1_0_1", - "remoteCommand": "startBatteryCharging", - "permission": "granted", - "requiredUserRole": "SECONDARY_USER", - "requiredSecurityLevel": "HG_2b", - "authenticationScope": [ - { - "content": "sc2:fal", - "authLevel": "T2" - } - ] - }, - { - "id": "G_JOBSTATUS", - "version": "1", - "permission": "granted", - "requiredUserRole": "SECONDARY_USER", - "requiredSecurityLevel": "HG_2b", - "authenticationScope": [ - { - "content": "sc2:fal", - "authLevel": "T2" - } - ] - }, - { - "id": "P_CURRENT", - "version": "1", - "xsd": "getAllChargingReportJob_v1_0_0", - "remoteCommand": "getAllChargingReport", - "permission": "granted", - "requiredUserRole": "SECONDARY_USER", - "requiredSecurityLevel": "HG_2b", - "authenticationScope": [ - { - "content": "sc2:fal", - "authLevel": "T2" - } - ] - }, - { - "id": "P_START", - "version": "1", - "xsd": "startBatteryChargingJob_v1_0_1", - "remoteCommand": "startBatteryCharging", - "permission": "granted", - "requiredUserRole": "SECONDARY_USER", - "requiredSecurityLevel": "HG_2b", - "authenticationScope": [ - { - "content": "sc2:fal", - "authLevel": "T2" - } - ] - }, - { - "id": "P_STOP", - "version": "1", - "xsd": "stopBatteryChargingJob_v1_0_0", - "remoteCommand": "stopBatteryCharging", - "permission": "granted", - "requiredUserRole": "SECONDARY_USER", - "requiredSecurityLevel": "HG_2b", - "authenticationScope": [ - { - "content": "sc2:fal", - "authLevel": "T2" - } - ] - }, - { - "id": "P_SETTINGS", - "version": "1", - "permission": "granted", - "requiredUserRole": "SECONDARY_USER", - "requiredSecurityLevel": "HG_2b", - "authenticationScope": [ - { - "content": "sc2:fal", - "authLevel": "T2" - } - ] - }, - { - "id": "G_SETTINGS", - "version": "1", - "permission": "granted", - "requiredUserRole": "SECONDARY_USER", - "requiredSecurityLevel": "HG_2b", - "authenticationScope": [ - { - "content": "sc2:fal", - "authLevel": "T2" - } - ] - } - ] - }, - { - "serviceId": "rolesrights_primaryuser_v2", - "serviceType": "mbb", - "serviceStatus": { - "status": "Enabled" - }, - "licenseRequired": false, - "primaryUserRequired": false, - "termsAndConditionsRequired": false, - "blockDisabling": false, - "personalized": false, - "configurable": false, - "deviceType": "OTHER", - "serviceEol": "2121-09-01T10:17:43Z", - "privacyGroups": null, - "parameters": null, - "rolesAndRightsRequired": false, - "invocationUrl": { - "content": "https://mal-1a.prd.ece.vwg-connect.com/api/rolesrights/primaryuser/v2/vehicles/{vin}/users/{userId}/" - }, - "operation": [ - { - "id": "assignPrimaryUser", - "version": "1", - "permission": "granted", - "requiredUserRole": "GUEST_USER", - "requiredSecurityLevel": "HG_0" - } - ] - }, - { - "serviceId": "trip_statistic_v1", - "serviceType": "mbb", - "serviceStatus": { - "status": "Enabled" - }, - "licenseRequired": true, - "cumulatedLicense": { - "status": "ACTIVATED", - "warn": false, - "activationBy": "automatic", - "activationDate": { - "content": "2019-11-29T00:00:00Z" - }, - "expirationDate": { - "content": "2029-11-29T00:00:00Z" - }, - "licenseProfiles": { - "lastUsedProfile": "LPBundle00000066", - "licenseProfile": [ - { - "content": "LPBundle00000066", - "ltype": "regular", - "profileType": "implicit", - "salesPartNo": "AU736Q7NFPHEVECE2", - "duration": "P10Y" - } - ] - } - }, - "primaryUserRequired": true, - "termsAndConditionsRequired": false, - "blockDisabling": false, - "personalized": false, - "configurable": false, - "deviceType": "TELEMATICS", - "serviceEol": "2120-08-31T13:50:52Z", - "privacyGroups": { - "privacyGroup": [ - "personalUser" - ] - }, - "parameters": null, - "rolesAndRightsRequired": true, - "invocationUrl": { - "content": "https://mal-1a.prd.ece.vwg-connect.com/api/bs/tripstatistics/v1/vehicles/{vin}/" - }, - "operation": [ - { - "id": "G_TRIPDATA", - "version": "1", - "permission": "granted", - "requiredUserRole": "SECONDARY_USER", - "requiredSecurityLevel": "HG_2b", - "authenticationScope": [ - { - "content": "sc2:fal", - "authLevel": "T2" - } - ] - }, - { - "id": "D_TRIPDATA", - "version": "1", - "permission": "granted", - "requiredUserRole": "SECONDARY_USER", - "requiredSecurityLevel": "HG_2b" - }, - { - "id": "G_AGGR_TRIPDATA", - "version": "1", - "permission": "granted", - "requiredUserRole": "SECONDARY_USER", - "requiredSecurityLevel": "HG_2b" - } - ] - }, - { - "serviceId": "primaryuser_v1", - "serviceType": "mbb", - "serviceStatus": { - "status": "Enabled" - }, - "licenseRequired": false, - "primaryUserRequired": false, - "termsAndConditionsRequired": false, - "blockDisabling": false, - "personalized": false, - "configurable": false, - "deviceType": "TELEMATICS", - "serviceEol": "2120-08-31T13:50:52Z", - "privacyGroups": { - "privacyGroup": [ - "personalUser" - ] - }, - "parameters": null, - "rolesAndRightsRequired": false - }, - { - "serviceId": "usermanagement_users_v1", - "serviceType": "mbb", - "serviceStatus": { - "status": "Enabled" - }, - "licenseRequired": false, - "primaryUserRequired": false, - "termsAndConditionsRequired": false, - "blockDisabling": false, - "personalized": false, - "configurable": false, - "deviceType": "OTHER", - "serviceEol": "2121-09-01T10:17:43Z", - "privacyGroups": null, - "parameters": null, - "rolesAndRightsRequired": false, - "invocationUrl": { - "content": "https://msg.audi.de/fs-car/usermanagement/users/v1/{brand}/{country}/" - }, - "operation": [ - { - "id": "getPairingStatus", - "version": "1", - "invocationUrl": { - "content": "https://msg.audi.de/fs-car/usermanagement/users/v1/{brand}/{country}/users/{userId}/vehicles/{vin}/", - "method": "GET" - }, - "permission": "granted", - "requiredUserRole": "GUEST_USER", - "requiredSecurityLevel": "HG_0" - }, - { - "id": "removePairing", - "version": "1", - "invocationUrl": { - "content": "https://msg.audi.de/fs-car/usermanagement/users/v1/{brand}/{country}/users/{userId}/vehicles/{vin}/", - "method": "DELETE" - }, - "permission": "granted", - "requiredUserRole": "GUEST_USER", - "requiredSecurityLevel": "HG_0" - }, - { - "id": "addPairing", - "version": "1", - "invocationUrl": { - "content": "https://msg.audi.de/fs-car/usermanagement/users/v1/{brand}/{country}/users/{userId}/vehicles/{vin}/", - "method": "PUT" - }, - "permission": "granted", - "requiredUserRole": "GUEST_USER", - "requiredSecurityLevel": "HG_0" - } - ] - }, - { - "serviceId": "rolesrights_secondaryuser_v2", - "serviceType": "mbb", - "serviceStatus": { - "status": "Enabled" - }, - "licenseRequired": false, - "primaryUserRequired": false, - "termsAndConditionsRequired": false, - "blockDisabling": false, - "personalized": false, - "configurable": false, - "deviceType": "OTHER", - "serviceEol": "2121-09-01T10:17:43Z", - "privacyGroups": null, - "parameters": null, - "rolesAndRightsRequired": false, - "invocationUrl": { - "content": "https://mal-1a.prd.ece.vwg-connect.com/api/rolesrights/secondaryuser/v2/vehicles/{vin}/users/{userId}/" - }, - "operation": [ - { - "id": "nominateSecondaryUser", - "version": "1", - "permission": "granted", - "requiredUserRole": "GUEST_USER", - "requiredSecurityLevel": "HG_0" - } - ] - }, - { - "serviceId": "rolesrights_secondaryuser_v1", - "serviceType": "mbb", - "serviceStatus": { - "status": "Enabled" - }, - "licenseRequired": false, - "primaryUserRequired": false, - "termsAndConditionsRequired": false, - "blockDisabling": false, - "personalized": false, - "configurable": false, - "deviceType": "OTHER", - "serviceEol": "2121-09-01T10:17:43Z", - "privacyGroups": null, - "parameters": null, - "rolesAndRightsRequired": false, - "invocationUrl": { - "content": "https://mal-1a.prd.ece.vwg-connect.com/api/rolesrights/secondaryuser/v1/vehicles/{vin}/users/{userId}/" - }, - "operation": [ - { - "id": "nominateSecondaryUser", - "version": "1", - "permission": "granted", - "requiredUserRole": "GUEST_USER", - "requiredSecurityLevel": "HG_0" - }, - { - "id": "revokeSecondaryUser", - "version": "1", - "permission": "granted", - "requiredUserRole": "GUEST_USER", - "requiredSecurityLevel": "HG_0" - } - ] - }, - { - "serviceId": "app_calendar_v1", - "serviceType": "app", - "serviceStatus": { - "status": "Enabled" - }, - "licenseRequired": false, - "primaryUserRequired": false, - "termsAndConditionsRequired": false, - "blockDisabling": false, - "personalized": false, - "configurable": false, - "deviceType": "INFOTAINMENT", - "serviceEol": "2121-08-30T14:06:06Z", - "privacyGroups": { - "privacyGroup": [ - "dormantService" - ] - }, - "parameters": { - "parameter": [ - { - "content": "1", - "name": "ttsSupported" - } - ] - }, - "rolesAndRightsRequired": false - }, - { - "serviceId": "rclima_v1", - "serviceType": "mbb", - "serviceStatus": { - "status": "Enabled" - }, - "licenseRequired": true, - "cumulatedLicense": { - "status": "ACTIVATED", - "warn": false, - "activationBy": "automatic", - "activationDate": { - "content": "2019-11-29T00:00:00Z" - }, - "expirationDate": { - "content": "2029-11-29T00:00:00Z" - }, - "licenseProfiles": { - "lastUsedProfile": "LPBundle00000066", - "licenseProfile": [ - { - "content": "LPBundle00000066", - "ltype": "regular", - "profileType": "implicit", - "salesPartNo": "AU736Q7NFPHEVECE2", - "duration": "P10Y" - } - ] - } - }, - "primaryUserRequired": true, - "termsAndConditionsRequired": false, - "blockDisabling": false, - "personalized": false, - "configurable": false, - "deviceType": "TELEMATICS", - "serviceEol": "2120-08-31T13:50:52Z", - "privacyGroups": { - "privacyGroup": [ - "personalUser" - ] - }, - "parameters": null, - "rolesAndRightsRequired": true, - "invocationUrl": { - "content": "https://mal-1a.prd.ece.vwg-connect.com/api/bs/climatisation/v1/vehicles/{vin}/" - }, - "operation": [ - { - "id": "G_SETTINGS", - "version": "1", - "permission": "granted", - "requiredUserRole": "SECONDARY_USER", - "requiredSecurityLevel": "HG_2b", - "authenticationScope": [ - { - "content": "sc2:fal", - "authLevel": "T2" - } - ] - }, - { - "id": "P_START_CLIMA_EL", - "version": "1", - "xsd": "startClimatisationJob_v1_0_2", - "remoteCommand": "startClimatisation", - "permission": "granted", - "requiredUserRole": "SECONDARY_USER", - "requiredSecurityLevel": "HG_2b", - "authenticationScope": [ - { - "content": "sc2:fal", - "authLevel": "T2" - } - ] - }, - { - "id": "G_STATUS", - "version": "1", - "permission": "granted", - "requiredUserRole": "SECONDARY_USER", - "requiredSecurityLevel": "HG_2b", - "authenticationScope": [ - { - "content": "sc2:fal", - "authLevel": "T2" - } - ] - }, - { - "id": "P_STOP", - "version": "1", - "xsd": "stopClimatisationJob_v1_0_0", - "remoteCommand": "stopClimatisation", - "permission": "granted", - "requiredUserRole": "SECONDARY_USER", - "requiredSecurityLevel": "HG_2b", - "authenticationScope": [ - { - "content": "sc2:fal", - "authLevel": "T2" - } - ] - }, - { - "id": "P_START_CLIMA_NOSET", - "version": "1", - "permission": "granted", - "requiredUserRole": "SECONDARY_USER", - "requiredSecurityLevel": "HG_2b", - "authenticationScope": [ - { - "content": "sc2:fal", - "authLevel": "T2" - } - ] - }, - { - "id": "G_DATA", - "version": "1", - "permission": "granted", - "requiredUserRole": "SECONDARY_USER", - "requiredSecurityLevel": "HG_2b", - "authenticationScope": [ - { - "content": "sc2:fal", - "authLevel": "T2" - } - ] - }, - { - "id": "G_JOBSTATUS", - "version": "1", - "permission": "granted", - "requiredUserRole": "SECONDARY_USER", - "requiredSecurityLevel": "HG_2b", - "authenticationScope": [ - { - "content": "sc2:fal", - "authLevel": "T2" - } - ] - }, - { - "id": "P_CURRENT", - "version": "1", - "xsd": "getAllClimatisationSettingsReportJob_v1_0_0", - "remoteCommand": "getAllClimatisationSettingsReport", - "permission": "granted", - "requiredUserRole": "SECONDARY_USER", - "requiredSecurityLevel": "HG_2b", - "authenticationScope": [ - { - "content": "sc2:fal", - "authLevel": "T2" - } - ] - } - ] - }, - { - "serviceId": "app_audishop_v1", - "serviceType": "app", - "serviceStatus": { - "status": "Enabled" - }, - "licenseRequired": false, - "primaryUserRequired": false, - "termsAndConditionsRequired": false, - "blockDisabling": false, - "personalized": false, - "configurable": false, - "deviceType": "INFOTAINMENT", - "serviceEol": "2121-08-30T14:06:06Z", - "privacyGroups": { - "privacyGroup": [ - "dormantService" - ] - }, - "parameters": null, - "rolesAndRightsRequired": false, - "operation": [ - { - "id": "shop_access", - "version": "1", - "permission": "granted", - "requiredUserRole": "ANONYMOUS_USER", - "requiredSecurityLevel": "HG_0" - } - ] - }, - { - "serviceId": "ecall_v1", - "serviceType": "mbb", - "serviceStatus": { - "status": "Enabled" - }, - "licenseRequired": true, - "cumulatedLicense": { - "status": "ACTIVATED", - "warn": false, - "activationBy": "automatic", - "activationDate": { - "content": "2019-11-29T00:00:00Z" - }, - "expirationDate": { - "content": "2029-11-29T00:00:00Z" - }, - "licenseProfiles": { - "lastUsedProfile": "LPBundle00000006", - "licenseProfile": [ - { - "content": "LPBundle00000006", - "ltype": "regular", - "profileType": "implicit", - "salesPartNo": "AU736Q7NFPHEVECE1", - "duration": "P10Y" - } - ] - } - }, - "primaryUserRequired": false, - "termsAndConditionsRequired": false, - "blockDisabling": true, - "personalized": false, - "configurable": false, - "deviceType": "TELEMATICS", - "serviceEol": "2030-11-03T23:00:00Z", - "privacyGroups": { - "privacyGroup": [ - "personalGps" - ] - }, - "parameters": null, - "rolesAndRightsRequired": false - }, - { - "serviceId": "appmedia_v1", - "serviceType": "app", - "serviceStatus": { - "status": "Enabled" - }, - "licenseRequired": false, - "primaryUserRequired": false, - "termsAndConditionsRequired": false, - "blockDisabling": false, - "personalized": false, - "configurable": true, - "deviceType": "INFOTAINMENT", - "serviceEol": "2121-08-30T14:06:06Z", - "privacyGroups": null, - "parameters": null, - "rolesAndRightsRequired": false - }, - { - "serviceId": "mobiledevicemgmt_v1", - "serviceType": "mbb", - "serviceStatus": { - "status": "Enabled" - }, - "licenseRequired": false, - "primaryUserRequired": false, - "termsAndConditionsRequired": false, - "blockDisabling": false, - "personalized": false, - "configurable": false, - "deviceType": "OTHER", - "serviceEol": "2121-09-01T10:17:43Z", - "privacyGroups": null, - "parameters": null, - "rolesAndRightsRequired": false, - "invocationUrl": { - "content": "https://mal-1a.prd.ece.vwg-connect.com/api/cs/mobiledevicemgmt/v1/" - }, - "operation": [ - { - "id": "registerMkiaaid", - "version": "1", - "invocationUrl": { - "content": "https://mal-1a.prd.ece.vwg-connect.com/api/cs/mobiledevicemgmt/v1/", - "method": "PUT" - }, - "permission": "granted", - "requiredUserRole": "GUEST_USER", - "requiredSecurityLevel": "HG_0" - } - ] - }, - { - "serviceId": "timerprogramming_v1", - "serviceType": "mbb", - "serviceStatus": { - "status": "Enabled" - }, - "licenseRequired": true, - "cumulatedLicense": { - "status": "ACTIVATED", - "warn": false, - "activationBy": "automatic", - "activationDate": { - "content": "2019-11-29T00:00:00Z" - }, - "expirationDate": { - "content": "2029-11-29T00:00:00Z" - }, - "licenseProfiles": { - "lastUsedProfile": "LPBundle00000066", - "licenseProfile": [ - { - "content": "LPBundle00000066", - "ltype": "regular", - "profileType": "implicit", - "salesPartNo": "AU736Q7NFPHEVECE2", - "duration": "P10Y" - } - ] - } - }, - "primaryUserRequired": true, - "termsAndConditionsRequired": false, - "blockDisabling": false, - "personalized": false, - "configurable": false, - "deviceType": "TELEMATICS", - "serviceEol": "2120-08-31T13:50:52Z", - "privacyGroups": { - "privacyGroup": [ - "personalUser" - ] - }, - "parameters": { - "parameter": [ - { - "content": "2", - "name": "chargeTimerCount" - }, - { - "content": "1", - "name": "heaterSourceSelectionAllowed" - }, - { - "content": "2", - "name": "climateTimerCount" - } - ] - }, - "rolesAndRightsRequired": true, - "invocationUrl": { - "content": "https://msg.audi.de/fs-car/bs/departuretimer/v1/{brand}/{country}/vehicles/{vin}/" - }, - "operation": [ - { - "id": "G_DATA", - "version": "1", - "permission": "granted", - "requiredUserRole": "SECONDARY_USER", - "requiredSecurityLevel": "HG_2b", - "authenticationScope": [ - { - "content": "sc2:fal", - "authLevel": "T2" - } - ] - }, - { - "id": "P_SETTINGS_EL", - "version": "1", - "xsd": "setDepartureTimersAndProfiles_V1_0_2", - "remoteCommand": "setDepartureTimersAndProfiles", - "permission": "granted", - "requiredUserRole": "SECONDARY_USER", - "requiredSecurityLevel": "HG_2b", - "authenticationScope": [ - { - "content": "sc2:fal", - "authLevel": "T2" - } - ] - }, - { - "id": "G_JOBSTATUS", - "version": "1", - "permission": "granted", - "requiredUserRole": "SECONDARY_USER", - "requiredSecurityLevel": "HG_2b", - "authenticationScope": [ - { - "content": "sc2:fal", - "authLevel": "T2" - } - ] - }, - { - "id": "G_SETTINGS", - "version": "1", - "permission": "granted", - "requiredUserRole": "SECONDARY_USER", - "requiredSecurityLevel": "HG_2b", - "authenticationScope": [ - { - "content": "sc2:fal", - "authLevel": "T2" - } - ] - }, - { - "id": "P_SETTING_CML", - "version": "1", - "permission": "granted", - "requiredUserRole": "SECONDARY_USER", - "requiredSecurityLevel": "HG_2b", - "authenticationScope": [ - { - "content": "sc2:fal", - "authLevel": "T2" - } - ] - }, - { - "id": "G_STATUS", - "version": "1", - "permission": "granted", - "requiredUserRole": "SECONDARY_USER", - "requiredSecurityLevel": "HG_2b", - "authenticationScope": [ - { - "content": "sc2:fal", - "authLevel": "T2" - } - ] - }, - { - "id": "P_CURRENT", - "version": "1", - "xsd": "getAllDepartureTimeReportJob_v1_0_0", - "remoteCommand": "getAllDepartureTimeReport", - "permission": "granted", - "requiredUserRole": "SECONDARY_USER", - "requiredSecurityLevel": "HG_2b", - "authenticationScope": [ - { - "content": "sc2:fal", - "authLevel": "T2" - } - ] - } - ] - }, - { - "serviceId": "lsd_v1", - "serviceType": "mbbInternal", - "serviceStatus": { - "status": "Enabled" - }, - "licenseRequired": false, - "primaryUserRequired": false, - "termsAndConditionsRequired": false, - "blockDisabling": true, - "personalized": false, - "configurable": false, - "deviceType": "INFOTAINMENT", - "serviceEol": "2121-08-30T14:06:06Z", - "privacyGroups": { - "privacyGroup": [ - "personalUser" - ] - }, - "parameters": { - "parameter": [ - { - "content": "0", - "name": "privacySettingsTransmitted" - } - ] - }, - "rolesAndRightsRequired": false - }, - { - "serviceId": "lsd_v1", - "serviceType": "mbbInternal", - "serviceStatus": { - "status": "Enabled" - }, - "licenseRequired": false, - "primaryUserRequired": false, - "termsAndConditionsRequired": false, - "blockDisabling": true, - "personalized": false, - "configurable": false, - "deviceType": "TELEMATICS", - "serviceEol": "2120-08-31T13:50:52Z", - "privacyGroups": { - "privacyGroup": [ - "personalUser" - ] - }, - "parameters": null, - "rolesAndRightsRequired": false - }, - { - "serviceId": "rolesrights_securitypin_v1", - "serviceType": "mbb", - "serviceStatus": { - "status": "Enabled" - }, - "licenseRequired": false, - "primaryUserRequired": false, - "termsAndConditionsRequired": false, - "blockDisabling": false, - "personalized": false, - "configurable": false, - "deviceType": "OTHER", - "serviceEol": "2121-09-01T10:17:43Z", - "privacyGroups": null, - "parameters": null, - "rolesAndRightsRequired": false, - "invocationUrl": { - "content": "https://mal-1a.prd.ece.vwg-connect.com/api/rolesrights/securitypin/v1/users/{userId}/" - }, - "operation": [ - { - "id": "prepareSecurityPinTransmission", - "version": "1", - "invocationUrl": { - "content": "https://msg.audi.de/fs-car/rolesrights/securitypin/v1/{brand}/{country}/users/{userId}/", - "method": "PUT" - }, - "permission": "granted", - "requiredUserRole": "GUEST_USER", - "requiredSecurityLevel": "HG_0" - }, - { - "id": "confirmRestoredSecurityPin", - "version": "1", - "invocationUrl": { - "content": "https://mal-1a.prd.ece.vwg-connect.com/api/rolesrights/securitypin/v1/vehicles/{vin}/", - "method": "POST" - }, - "permission": "granted", - "requiredUserRole": "GUEST_USER", - "requiredSecurityLevel": "HG_0" - } - ] - }, - { - "serviceId": "twitter_v3", - "serviceType": "mbb", - "serviceStatus": { - "status": "Enabled" - }, - "licenseRequired": true, - "cumulatedLicense": { - "status": "ACTIVATED", - "warn": false, - "activationBy": "automatic", - "activationDate": { - "content": "2019-11-29T00:00:00Z" - }, - "expirationDate": { - "content": "2022-11-29T00:00:00Z" - }, - "licenseProfiles": { - "lastUsedProfile": "LPBundle00000423", - "licenseProfile": [ - { - "content": "LPBundle00000423", - "ltype": "regular", - "profileType": "implicit", - "duration": "P3Y" - } - ] - } - }, - "primaryUserRequired": false, - "termsAndConditionsRequired": false, - "blockDisabling": false, - "personalized": false, - "configurable": true, - "deviceType": "INFOTAINMENT", - "serviceEol": "2121-08-30T14:06:06Z", - "privacyGroups": null, - "parameters": null, - "rolesAndRightsRequired": false, - "invocationUrl": { - "content": "https://msg.audi.de/fs-car/social/twitter/v1/{brand}/{country}/vehicles/{vin}/" - } - }, - { - "serviceId": "rolesrights_primaryuser_v1", - "serviceType": "mbb", - "serviceStatus": { - "status": "Enabled" - }, - "licenseRequired": false, - "primaryUserRequired": false, - "termsAndConditionsRequired": false, - "blockDisabling": false, - "personalized": false, - "configurable": false, - "deviceType": "OTHER", - "serviceEol": "2121-09-01T10:17:43Z", - "privacyGroups": null, - "parameters": null, - "rolesAndRightsRequired": false, - "invocationUrl": { - "content": "https://mal-1a.prd.ece.vwg-connect.com/api/rolesrights/primaryuser/v1/vehicles/{vin}/users/{userId}/" - }, - "operation": [ - { - "id": "revokePrimaryUser", - "version": "1", - "permission": "granted", - "requiredUserRole": "GUEST_USER", - "requiredSecurityLevel": "HG_0" - } - ] - } - ], - "privacyGroupStates": { - "privacyGroupState": [ - { - "privacyGroup": "personalGps", - "privacyGroupEnabled": true - }, - { - "privacyGroup": "pseudonymousGps", - "privacyGroupEnabled": true - }, - { - "privacyGroup": "personalUser", - "privacyGroupEnabled": true - }, - { - "privacyGroup": "personalVehicle", - "privacyGroupEnabled": true - }, - { - "privacyGroup": "anonymousData", - "privacyGroupEnabled": true - }, - { - "privacyGroup": "anonymousDataNoGPS", - "privacyGroupEnabled": true - }, - { - "privacyGroup": "dormantService", - "privacyGroupEnabled": true - } - ] - } - } -} diff --git a/vehicle/vw/types.go b/vehicle/vw/types.go deleted file mode 100644 index 7888e0b9d..000000000 --- a/vehicle/vw/types.go +++ /dev/null @@ -1,155 +0,0 @@ -package vw - -import ( - "encoding/json" - "fmt" - "math" - "strconv" - "time" -) - -type Error struct { - ErrorCode, Description string -} - -func (e *Error) Error() error { - return fmt.Errorf("%s: %s", e.ErrorCode, e.Description) -} - -// ChargerResponse is the /bs/batterycharge/v1/%s/%s/vehicles/%s/charger api -type ChargerResponse struct { - Charger struct { - Status struct { - BatteryStatusData struct { - StateOfCharge TimedInt - RemainingChargingTime TimedInt - } - ChargingStatusData struct { - ChargingState TimedString // off, charging - ChargingMode TimedString // invalid, AC - ChargingReason TimedString // invalid, immediate - ExternalPowerSupplyState TimedString // unavailable, available - EnergyFlow TimedString // on, off - } - PlugStatusData struct { - PlugState TimedString // connected - } - CruisingRangeStatusData struct { - EngineTypeFirstEngine TimedString // typeIsElectric, petrolGasoline - EngineTypeSecondEngine TimedString // typeIsElectric, petrolGasoline - PrimaryEngineRange TimedInt - SecondaryEngineRange TimedInt - HybridRange TimedInt - } - } - } - Error *Error // optional error -} - -// ClimaterResponse is the /bs/climatisation/v1/%s/%s/vehicles/%s/climater api -type ClimaterResponse struct { - Climater struct { - Settings struct { - TargetTemperature TimedTemperature - HeaterSource TimedString - } - Status struct { - ClimatisationStatusData struct { - ClimatisationState TimedString - ClimatisationReason TimedString - RemainingClimatisationTime TimedInt - } - TemperatureStatusData struct { - OutdoorTemperature TimedTemperature - } - VehicleParkingClockStatusData struct { - VehicleParkingClock TimedString - } - } - } - Error *Error // optional error -} - -// PositionResponse is the /bs/cf/v1/%s/%s/vehicles/%s/position api -type PositionResponse struct { - FindCarResponse struct { - Position struct { - TimestampCarSent string // "2021-12-12T16:42:44" - TimestampTssReceived time.Time - CarCoordinate struct { - Latitude int64 - Longitude int64 - } - TimestampCarSentUTC time.Time - TimestampCarCaptured string // "2021-12-12T16:42:44" - } - ParkingTimeUTC time.Time - } - Error *Error // optional error -} - -// VehiclesResponse is the /usermanagement/users/v1/%s/%s/vehicles api -type VehiclesResponse struct { - UserVehicles struct { - Vehicle []string - } - Error *Error // optional error -} - -// HomeRegion is the home region API response -type HomeRegion struct { - HomeRegion struct { - BaseURI struct { - SystemID string - Content string // api url - } - } - Error *Error // optional error -} - -// TimedInt is an int value with timestamp -type TimedInt struct { - Content int - Timestamp string -} - -// TimedString is a string value with timestamp -type TimedString struct { - Content string - Timestamp string -} - -// TimedTemperature is the api temperature with timestamp -type TimedTemperature struct { - Content float64 - Timestamp string -} - -func (t *TimedTemperature) UnmarshalJSON(data []byte) error { - var temp struct { - Content json.RawMessage // handle "invalid" - Timestamp string - } - - err := json.Unmarshal(data, &temp) - if err == nil { - t.Timestamp = temp.Timestamp - - if val, err := strconv.Atoi(string(temp.Content)); err == nil { - t.Content = temp2Float(val) - } else { - t.Content = math.NaN() - } - } - - return err -} - -// temp2Float converts api temp to float value -func temp2Float(i int) float64 { - f := float64(i) - if f == 0 { - return math.NaN() - } - return f/10 - 273 -} diff --git a/vehicle/vw/types_rolesrights.go b/vehicle/vw/types_rolesrights.go deleted file mode 100644 index 1c7bcb2b9..000000000 --- a/vehicle/vw/types_rolesrights.go +++ /dev/null @@ -1,39 +0,0 @@ -package vw - -const StatusService = "statusreport_v1" - -// RolesRights is the /rolesrights/operationlist response -type RolesRights struct { - OperationList struct { - VIN, UserId, Role, Status string - ServiceInfo []ServiceInfo - } -} - -func (rr RolesRights) ServiceByID(id string) *ServiceInfo { - for _, s := range rr.OperationList.ServiceInfo { - if s.ServiceId == id { - return &s - } - } - return nil -} - -// ServiceInfo is the rolesrights service information -type ServiceInfo struct { - ServiceId string - ServiceType string - ServiceStatus struct { - Status string - } - LicenseRequired bool - CumulatedLicense map[string]any - PrimaryUserRequired bool - TermsAndConditionsRequired bool - ServiceEol string - RolesAndRightsRequired bool - InvocationUrl struct { - Content string - } - Operation []map[string]any -} diff --git a/vehicle/vw/types_status.go b/vehicle/vw/types_status.go deleted file mode 100644 index e8e8486ab..000000000 --- a/vehicle/vw/types_status.go +++ /dev/null @@ -1,53 +0,0 @@ -package vw - -const ServiceOdometer = "0x0101010002" - -type StatusResponse struct { - StoredVehicleDataResponse struct { - VIN string - VehicleData struct { - Data []ServiceDefinition - } - } - Error *Error -} - -func (s *StatusResponse) ServiceByID(id string) *ServiceDefinition { - for _, d := range s.StoredVehicleDataResponse.VehicleData.Data { - if d.ID == id { - return &d - } - } - - return nil -} - -type ServiceDefinition struct { - ID string - Field []FieldDefinition -} - -func (s *ServiceDefinition) FieldByID(id string) *FieldDefinition { - if s == nil { - return nil - } - - for _, f := range s.Field { - if f.ID == id { - return &f - } - } - - return nil -} - -type FieldDefinition struct { - ID string // "0x0101010001", - TsCarSentUtc string // "2021-09-05T07:54:20Z", - TsCarSent string // "2021-09-05T07:54:19", - TsCarCaptured string // "2021-09-05T07:54:19", - TsTssReceivedUtc string // "2021-09-05T07:54:23Z", - MilCarCaptured int // 25009, - MilCarSent int // 25009, - Value string // "echo" -} diff --git a/vehicle/vw/types_test.go b/vehicle/vw/types_test.go deleted file mode 100644 index 1b638b905..000000000 --- a/vehicle/vw/types_test.go +++ /dev/null @@ -1,43 +0,0 @@ -package vw - -import ( - "encoding/json" - "math" - "testing" -) - -func TestTemp(t *testing.T) { - data := `[{ - "content": 2930, - "timestamp": "time" - }, { - "content": "invalid", - "timestamp": "time" - }]` - - var temps []TimedTemperature - if err := json.Unmarshal([]byte(data), &temps); err != nil { - t.Error(err) - } else { - if v := temps[0].Content; v != 20 { - t.Error("invalid temp 0", v) - } - if v := temps[1].Content; !math.IsNaN(v) { - t.Error("invalid temp 1", v) - } - } -} - -func TestError(t *testing.T) { - data := `{"error":{"errorCode":"batterycharge.auth.forbidden","description":"The context has not gained a legitimation due to missing access rights."}}` - var res ChargerResponse - if err := json.Unmarshal([]byte(data), &res); err != nil { - t.Error(err) - } - if res.Error == nil { - t.Fatal("Error is nil") - } - if res.Error.ErrorCode == "" { - t.Error("ErrorCode is empty") - } -} diff --git a/vehicle/vw/weconnect/api.go b/vehicle/vw/weconnect/api.go deleted file mode 100644 index ca98c3df8..000000000 --- a/vehicle/vw/weconnect/api.go +++ /dev/null @@ -1,119 +0,0 @@ -package weconnect - -import ( - "fmt" - "net/http" - "strings" - - "github.com/evcc-io/evcc/util" - "github.com/evcc-io/evcc/util/request" - "golang.org/x/oauth2" -) - -// https://identity-userinfo.vwgroup.io/oidc/userinfo -// https://customer-profile.apps.emea.vwapps.io/v1/customers//realCarData - -// BaseURL is the API base url -const BaseURL = "https://emea.bff.cariad.digital/vehicle/v1" - -// API is an api.Vehicle implementation for VW ID cars -type API struct { - *request.Helper -} - -// Actions and action values -const ( - ActionCharge = "charging" - ActionChargeStart = "start" - ActionChargeStop = "stop" - ActionChargeSettings = "settings" // body: targetSOC_pct - - ActionClimatisation = "climatisation" - ActionClimatisationStart = "start" - ActionClimatisationStop = "stop" -) - -// NewAPI creates a new vehicle -func NewAPI(log *util.Logger, ts oauth2.TokenSource) *API { - v := &API{ - Helper: request.NewHelper(log), - } - - v.Client.Transport = &oauth2.Transport{ - Source: ts, - Base: v.Client.Transport, - } - - return v -} - -// Vehicles implements the /vehicles response -func (v *API) Vehicles() ([]Vehicle, error) { - var res Vehicles - - uri := fmt.Sprintf("%s/vehicles", BaseURL) - req, err := request.New(http.MethodGet, uri, nil, request.AcceptJSON) - - if err == nil { - err = v.DoJSON(req, &res) - } - - return res.Data, err -} - -// Status implements the /status response. -// It is callers responsibility to check for embedded (partial) errors. -func (v *API) Status(vin string) (res Status, err error) { - uri := fmt.Sprintf("%s/vehicles/%s/selectivestatus?jobs=charging,fuelStatus,climatisation,measurements", BaseURL, vin) - - req, err := request.New(http.MethodGet, uri, nil, request.AcceptJSON) - - if err == nil { - err = v.DoJSON(req, &res) - } - - return res, err -} - -// ParkingPosition implements the /parkingposition response -func (v *API) ParkingPosition(vin string) (ParkingPosition, error) { - var res ParkingPosition - uri := fmt.Sprintf("%s/vehicles/%s/parkingposition", BaseURL, vin) - - req, err := request.New(http.MethodGet, uri, nil, request.AcceptJSON) - if err == nil { - err = v.DoJSON(req, &res) - } - - return res, err -} - -// Action implements vehicle actions -func (v *API) Action(vin, action, value string) error { - uri := fmt.Sprintf("%s/vehicles/%s/%s/%s", BaseURL, vin, action, value) - - req, err := request.New(http.MethodPost, uri, nil, request.AcceptJSON) - - if err == nil { - var res any - err = v.DoJSON(req, &res) - } - - return err -} - -// Any implements any api response -func (v *API) Any(uri, vin string) (any, error) { - if strings.Contains(uri, "%s") { - uri = fmt.Sprintf(uri, vin) - } - - req, err := request.New(http.MethodGet, uri, nil, request.AcceptJSON) - - var res any - if err == nil { - err = v.DoJSON(req, &res) - } - - return res, err -} diff --git a/vehicle/vw/weconnect/oauth.go b/vehicle/vw/weconnect/oauth.go deleted file mode 100644 index 206e7a893..000000000 --- a/vehicle/vw/weconnect/oauth.go +++ /dev/null @@ -1,71 +0,0 @@ -package weconnect - -import ( - "net/http" - "net/url" - "strings" - "time" - - "github.com/evcc-io/evcc/util" - "github.com/evcc-io/evcc/util/oauth" - "github.com/evcc-io/evcc/util/request" - "github.com/evcc-io/evcc/util/urlvalues" - "github.com/evcc-io/evcc/vehicle/vag/cariad" - "golang.org/x/oauth2" -) - -const tokenURL = cariad.BaseURL + "/auth/v1/idk/oidc/token" - -// ExchangeCode swaps the authorization code from the OIDC callback for an -// access/refresh token pair at the cariad BFF OIDC token endpoint. Replaces -// the legacy WeConnect SSO exchange (/user-login/login/v1), which VW removed -// in May 2026. -func ExchangeCode(log *util.Logger, q url.Values) (*oauth2.Token, error) { - if err := urlvalues.Require(q, "code", "code_verifier"); err != nil { - return nil, err - } - - data := url.Values{ - "grant_type": {"authorization_code"}, - "code": {q.Get("code")}, - "code_verifier": {q.Get("code_verifier")}, - "redirect_uri": {"weconnect://authenticated"}, - "client_id": {cariad.ClientID}, - } - - return postToken(log, data) -} - -// TokenSource returns a refreshing oauth2.TokenSource that swaps refresh -// tokens for fresh access tokens at the same OIDC token endpoint. -func TokenSource(log *util.Logger, token *oauth2.Token) oauth2.TokenSource { - return oauth.RefreshTokenSource(token, func(t *oauth2.Token) (*oauth2.Token, error) { - data := url.Values{ - "grant_type": {"refresh_token"}, - "refresh_token": {t.RefreshToken}, - "client_id": {cariad.ClientID}, - } - return postToken(log, data) - }) -} - -func postToken(log *util.Logger, data url.Values) (*oauth2.Token, error) { - req, err := request.New(http.MethodPost, tokenURL, strings.NewReader(data.Encode()), - map[string]string{ - "Content-Type": request.FormContent, - "Accept": request.JSONContent, - "User-Agent": cariad.UserAgent, - "x-android-package-name": cariad.AndroidPackageName, - }) - if err != nil { - return nil, err - } - - var token oauth2.Token - if err := request.NewHelper(log).DoJSON(req, &token); err != nil { - return nil, err - } - - token.Expiry = time.Now().Add(time.Duration(token.ExpiresIn) * time.Second) - return &token, nil -} diff --git a/vehicle/vw/weconnect/params.go b/vehicle/vw/weconnect/params.go deleted file mode 100644 index 65f41fb68..000000000 --- a/vehicle/vw/weconnect/params.go +++ /dev/null @@ -1,18 +0,0 @@ -package weconnect - -import ( - "net/url" - - "github.com/evcc-io/evcc/vehicle/vag/cariad" -) - -// AuthParams are the OIDC authorize parameters for the WeConnect ID client. -// The authorize endpoint is the legacy identity.vwgroup.io OIDC entry point -// (vwidentity.Config.AuthURL); the token endpoint is the cariad BFF (see -// oauth.go). -var AuthParams = url.Values{ - "response_type": {"code id_token token"}, - "client_id": {cariad.ClientID}, - "redirect_uri": {"weconnect://authenticated"}, - "scope": {"openid profile badge cars vin"}, // dealers -} diff --git a/vehicle/vw/weconnect/provider.go b/vehicle/vw/weconnect/provider.go deleted file mode 100644 index c7af32dc3..000000000 --- a/vehicle/vw/weconnect/provider.go +++ /dev/null @@ -1,189 +0,0 @@ -package weconnect - -import ( - "errors" - "strings" - "time" - - "github.com/evcc-io/evcc/api" - "github.com/evcc-io/evcc/util" -) - -// Provider is an api.Vehicle implementation for VW ID cars -type Provider struct { - statusG func() (Status, error) - positionG func() (ParkingPosition, error) - action func(action, value string) error -} - -// NewProvider creates a vehicle api provider -func NewProvider(api *API, vin string, cache time.Duration) *Provider { - impl := &Provider{ - statusG: util.Cached(func() (Status, error) { - return api.Status(vin) - }, cache), - positionG: util.Cached(func() (ParkingPosition, error) { - return api.ParkingPosition(vin) - }, cache), - action: func(action, value string) error { - return api.Action(vin, action, value) - }, - } - return impl -} - -var _ api.Battery = (*Provider)(nil) - -// Soc implements the api.Vehicle interface -func (v *Provider) Soc() (float64, error) { - res, err := v.statusG() - - if err == nil && res.Charging == nil { - err = errors.New("missing charging status") - } - - if err == nil { - return float64(res.Charging.BatteryStatus.Value.CurrentSOCPct), nil - } - - return 0, err -} - -var _ api.ChargeState = (*Provider)(nil) - -// Status implements the api.ChargeState interface -func (v *Provider) Status() (api.ChargeStatus, error) { - status := api.StatusA // disconnected - - res, err := v.statusG() - if err != nil { - return status, err - } - - if res.Charging == nil { - return status, errors.New("missing charging status") - } - - if res.Charging.PlugStatus.Value.PlugConnectionState == "connected" { - status = api.StatusB - } - if res.Charging.ChargingStatus.Value.ChargingState == "charging" { - status = api.StatusC - } - - return status, nil -} - -var _ api.VehicleFinishTimer = (*Provider)(nil) - -// FinishTime implements the api.VehicleFinishTimer interface -func (v *Provider) FinishTime() (time.Time, error) { - res, err := v.statusG() - if err != nil { - return time.Time{}, err - } - - if res.Charging == nil { - return time.Time{}, errors.New("missing charging status") - } - - cst := res.Charging.ChargingStatus.Value - return cst.CarCapturedTimestamp.Add(time.Duration(cst.RemainingChargingTimeToCompleteMin) * time.Minute), nil -} - -var _ api.VehicleRange = (*Provider)(nil) - -// Range implements the api.VehicleRange interface -func (v *Provider) Range() (int64, error) { - res, err := v.statusG() - if err != nil { - return 0, err - } - - if res.Charging == nil { - return 0, errors.New("missing charging status") - } - - return int64(res.Charging.BatteryStatus.Value.CruisingRangeElectricKm), nil -} - -var _ api.VehicleOdometer = (*Provider)(nil) - -// Odometer implements the api.VehicleOdometer interface -func (v *Provider) Odometer() (float64, error) { - res, err := v.statusG() - if err == nil && res.Measurements == nil { - err = api.ErrNotAvailable - } - - if err == nil { - return res.Measurements.OdometerStatus.Value.Odometer, nil - } - - return 0, err -} - -var _ api.VehicleClimater = (*Provider)(nil) - -// Climater implements the api.VehicleClimater interface -func (v *Provider) Climater() (bool, error) { - res, err := v.statusG() - if err == nil && res.Climatisation == nil { - err = api.ErrNotAvailable - } - - if err == nil { - state := strings.ToLower(res.Climatisation.ClimatisationStatus.Value.ClimatisationState) - if state == "" { - return false, api.ErrNotAvailable - } - - active := state != "off" && state != "invalid" && state != "error" - return active, nil - } - - return false, err -} - -var _ api.SocLimiter = (*Provider)(nil) - -// GetLimitSoc implements the api.SocLimiter interface -func (v *Provider) GetLimitSoc() (int64, error) { - res, err := v.statusG() - if err != nil || res.Charging == nil || res.Charging.ChargingSettings.Value.TargetSOCPct == nil { - return 0, api.ErrNotAvailable - } - - return int64(*res.Charging.ChargingSettings.Value.TargetSOCPct), nil -} - -var _ api.ChargeController = (*Provider)(nil) - -// ChargeEnable implements the api.ChargeController interface -func (v *Provider) ChargeEnable(enable bool) error { - action := map[bool]string{true: ActionChargeStart, false: ActionChargeStop} - return v.action(ActionCharge, action[enable]) -} - -var _ api.VehiclePosition = (*Provider)(nil) - -// Position implements the api.VehiclePosition interface -func (v *Provider) Position() (float64, float64, error) { - res, err := v.positionG() - if res.Latitude == 0 && res.Longitude == 0 { - err = api.ErrNotAvailable - } - - if err != nil { - return 0, 0, err - } - - return res.Latitude, res.Longitude, nil -} - -var _ api.Resurrector = (*Provider)(nil) - -// WakeUp implements the api.Resurrector interface -func (v *Provider) WakeUp() error { - return v.ChargeEnable(true) -} diff --git a/vehicle/vw/weconnect/types.go b/vehicle/vw/weconnect/types.go deleted file mode 100644 index 4da347c87..000000000 --- a/vehicle/vw/weconnect/types.go +++ /dev/null @@ -1,380 +0,0 @@ -package weconnect - -import ( - "encoding/json" - "errors" - "fmt" - "strings" - "time" -) - -// Vehicles is the /vehicles api -type Vehicles struct { - Data []Vehicle -} - -// Vehicle is the api vehicle -type Vehicle struct { - VIN string - Model string - Nickname string -} - -// Status is the /status api -type Status struct { - Access *struct { - AccessStatus struct { - Value struct { - OverallStatus string `json:"overallStatus"` - CarCapturedTimestamp Timestamp `json:"carCapturedTimestamp"` - Doors []struct { - Name string `json:"name"` - Status []string `json:"status"` - } `json:"doors"` - Windows []struct { - Name string `json:"name"` - Status []string `json:"status"` - } `json:"windows"` - DoorLockStatus string `json:"doorLockStatus"` - } `json:"value"` - } `json:"accessStatus"` - } `json:"access"` - Automation *struct { - ClimatisationTimer struct { - Value struct { - Timers []struct { - ID int `json:"id"` - Enabled bool `json:"enabled"` - RecurringTimer struct { - StartTime string `json:"startTime"` - RecurringOn struct { - Mondays bool `json:"mondays"` - Tuesdays bool `json:"tuesdays"` - Wednesdays bool `json:"wednesdays"` - Thursdays bool `json:"thursdays"` - Fridays bool `json:"fridays"` - Saturdays bool `json:"saturdays"` - Sundays bool `json:"sundays"` - } `json:"recurringOn"` - } `json:"recurringTimer,omitempty"` - SingleTimer struct { - StartDateTime Timestamp `json:"startDateTime"` - } `json:"singleTimer,omitempty"` - } `json:"timers"` - CarCapturedTimestamp Timestamp `json:"carCapturedTimestamp"` - TimeInCar string `json:"timeInCar"` - } `json:"value"` - } `json:"climatisationTimer"` - ChargingProfiles *struct { - Value struct { - CarCapturedTimestamp Timestamp `json:"carCapturedTimestamp"` - TimeInCar string `json:"timeInCar"` - Profiles []any `json:"profiles"` - } `json:"value"` - } `json:"chargingProfiles"` - } `json:"automation"` - UserCapabilities *struct { - CapabilitiesStatus struct { - Value []struct { - ID string `json:"id"` - UserDisablingAllowed bool `json:"userDisablingAllowed"` - ExpirationDate Timestamp `json:"expirationDate,omitempty"` - Status []int `json:"status,omitempty"` - } `json:"value"` - } `json:"capabilitiesStatus"` - } `json:"userCapabilities"` - Charging *struct { - BatteryStatus struct { - Value struct { - CarCapturedTimestamp Timestamp `json:"carCapturedTimestamp"` - CurrentSOCPct int `json:"currentSOC_pct"` - CruisingRangeElectricKm int `json:"cruisingRangeElectric_km"` - } `json:"value"` - } `json:"batteryStatus"` - ChargingStatus struct { - Value struct { - CarCapturedTimestamp Timestamp `json:"carCapturedTimestamp"` - RemainingChargingTimeToCompleteMin int `json:"remainingChargingTimeToComplete_min"` - ChargingState string `json:"chargingState"` // readyForCharging/off - ChargeMode string `json:"chargeMode"` // invalid - ChargePowerKW float64 `json:"chargePower_kW"` - ChargeRateKmph float64 `json:"chargeRate_kmph"` - ChargeType string `json:"chargeType"` - ChargingSettings string `json:"chargingSettings"` - } `json:"value"` - } `json:"chargingStatus"` - ChargingSettings struct { - Value struct { - CarCapturedTimestamp Timestamp `json:"carCapturedTimestamp"` - MaxChargeCurrentAC string `json:"maxChargeCurrentAC"` // reduced, maximum - AutoUnlockPlugWhenCharged string `json:"autoUnlockPlugWhenCharged"` - AutoUnlockPlugWhenChargedAC string `json:"autoUnlockPlugWhenChargedAC"` - TargetSOCPct *int `json:"targetSOC_pct"` - } `json:"value"` - } `json:"chargingSettings"` - PlugStatus struct { - Value struct { - CarCapturedTimestamp Timestamp `json:"carCapturedTimestamp"` - PlugConnectionState string `json:"plugConnectionState"` // connected, disconnected - PlugLockState string `json:"plugLockState"` // locked, unlocked - ExternalPower string `json:"externalPower"` - LedColor string `json:"ledColor"` - } `json:"value"` - } `json:"plugStatus"` - ChargeMode struct { - Value struct { - PreferredChargeMode string `json:"preferredChargeMode"` - AvailableChargeModes []string `json:"availableChargeModes"` - } `json:"value"` - } `json:"chargeMode"` - ChargingCareSettings struct { - Value struct { - BatteryCareMode string `json:"batteryCareMode"` - } `json:"value"` - } `json:"chargingCareSettings"` - } `json:"charging"` - Climatisation *struct { - ClimatisationStatus struct { - Value struct { - CarCapturedTimestamp Timestamp `json:"carCapturedTimestamp"` - RemainingClimatisationTimeMin int `json:"remainingClimatisationTime_min"` - ClimatisationState string `json:"climatisationState"` // off - } `json:"value"` - } `json:"climatisationStatus"` // may be temporarily not available - ClimatisationSettings struct { - Value struct { - CarCapturedTimestamp Timestamp `json:"carCapturedTimestamp"` - TargetTemperatureC float64 `json:"targetTemperature_C"` - TargetTemperatureF float64 `json:"targetTemperature_F"` - UnitInCar string `json:"unitInCar"` - ClimatizationAtUnlock bool `json:"climatizationAtUnlock"` // ClimatizationAtUnlock? - WindowHeatingEnabled bool `json:"windowHeatingEnabled"` - ZoneFrontLeftEnabled bool `json:"zoneFrontLeftEnabled"` - ZoneFrontRightEnabled bool `json:"zoneFrontRightEnabled"` - } `json:"value"` - } `json:"climatisationSettings"` - WindowHeatingStatus struct { - Value struct { - CarCapturedTimestamp Timestamp `json:"carCapturedTimestamp"` - WindowHeatingStatus []struct { - WindowLocation string `json:"windowLocation"` - WindowHeatingState string `json:"windowHeatingState"` - } `json:"windowHeatingStatus"` - } `json:"value"` - } `json:"windowHeatingStatus"` - } `json:"climatisation"` - ClimatisationTimers *struct { - ClimatisationTimersStatus struct { - Value struct { - Timers []struct { - ID int `json:"id"` - Enabled bool `json:"enabled"` - RecurringTimer struct { - StartTime string `json:"startTime"` - RecurringOn struct { - Mondays bool `json:"mondays"` - Tuesdays bool `json:"tuesdays"` - Wednesdays bool `json:"wednesdays"` - Thursdays bool `json:"thursdays"` - Fridays bool `json:"fridays"` - Saturdays bool `json:"saturdays"` - Sundays bool `json:"sundays"` - } `json:"recurringOn"` - } `json:"recurringTimer,omitempty"` - SingleTimer struct { - StartDateTime Timestamp `json:"startDateTime"` - } `json:"singleTimer"` - } `json:"timers"` - CarCapturedTimestamp Timestamp `json:"carCapturedTimestamp"` - TimeInCar string `json:"timeInCar"` - } `json:"value"` - } `json:"climatisationTimersStatus"` - } `json:"climatisationTimers"` - VehicleLights *struct { - LightsStatus struct { - Value struct { - CarCapturedTimestamp Timestamp `json:"carCapturedTimestamp"` - Lights []struct { - Name string `json:"name"` - Status string `json:"status"` - } `json:"lights"` - } `json:"value"` - } `json:"lightsStatus"` - } `json:"vehicleLights"` - Measurements *struct { - RangeStatus struct { - Value struct { - CarCapturedTimestamp Timestamp `json:"carCapturedTimestamp"` - ElectricRange float64 `json:"electricRange"` - } `json:"value"` - } `json:"rangeStatus"` - OdometerStatus struct { - Value struct { - CarCapturedTimestamp Timestamp `json:"carCapturedTimestamp"` - Odometer float64 `json:"odometer"` - } `json:"value"` - } `json:"odometerStatus"` - } `json:"measurements"` - FuelStatus *FuelStatus `json:"fuelStatus"` - Readiness *struct { - ReadinessStatus struct { - Value struct { - ConnectionState struct { - IsOnline bool `json:"isOnline"` - IsActive bool `json:"isActive"` - BatteryPowerLevel string `json:"batteryPowerLevel"` - DailyPowerBudgetAvailable bool `json:"dailyPowerBudgetAvailable"` - } `json:"connectionState"` - ConnectionWarning struct { - InsufficientBatteryLevelWarning bool `json:"insufficientBatteryLevelWarning"` - DailyPowerBudgetWarning bool `json:"dailyPowerBudgetWarning"` - } `json:"connectionWarning"` - } `json:"value"` - } `json:"readinessStatus"` - } `json:"readiness"` - VehicleHealthWarnings *struct { - WarningLights struct { - Value struct { - CarCapturedTimestamp Timestamp `json:"carCapturedTimestamp"` - MileageKm int `json:"mileage_km"` - WarningLights []any `json:"warningLights"` - } `json:"value"` - } `json:"warningLights"` - } `json:"vehicleHealthWarnings"` - ChargingTimers *struct { - ChargingTimersStatus struct { - Value struct { - CarCapturedTimestamp Timestamp `json:"carCapturedTimestamp"` - TimeInCar string `json:"timeInCar"` - Timers []struct { - ID int `json:"id"` - Enabled bool `json:"enabled"` - Climatisation bool `json:"climatisation"` - RecurringTimer struct { - DepartureTime string `json:"departureTime"` - RepetitionDays []string `json:"repetitionDays"` - } `json:"recurringTimer"` - } `json:"timers"` - } `json:"value"` - } `json:"chargingTimersStatus"` - } `json:"chargingTimers"` - ChargingProfiles *struct { - ChargingProfilesStatus struct { - Value struct { - CarCapturedTimestamp Timestamp `json:"carCapturedTimestamp"` - TimeInCar string `json:"timeInCar"` - Profiles []struct { - ID int `json:"id"` - Name string `json:"name"` - MaxChargingCurrent string `json:"maxChargingCurrent"` - MinSOCPct int `json:"minSOC_pct"` - TargetSOCPct int `json:"targetSOC_pct"` - Options struct { - AutoUnlockPlugWhenCharged string `json:"autoUnlockPlugWhenCharged"` - } `json:"options"` - PreferredChargingTimes []struct { - ID int `json:"id"` - Enabled bool `json:"enabled"` - StartTime string `json:"startTime"` - EndTime string `json:"endTime"` - } `json:"preferredChargingTimes"` - Timers []any `json:"timers"` - MinSOCEnabled bool `json:"minSOC_enabled"` - } `json:"profiles"` - } `json:"value"` - } `json:"chargingProfilesStatus"` - } `json:"chargingProfiles"` -} - -// FuelStatus is the engine range status -type FuelStatus struct { - RangeStatus struct { - Value struct { - CarCapturedTimestamp Timestamp `json:"carCapturedTimestamp"` - CarType string `json:"carType"` - PrimaryEngine EngineRangeStatus `json:"primaryEngine"` - SecondaryEngine EngineRangeStatus `json:"secondaryEngine"` - TotalRangeKm int `json:"totalRange_km"` - } `json:"value"` - } `json:"rangeStatus"` -} - -func (f *FuelStatus) EngineRangeStatus(typ string) (EngineRangeStatus, error) { - if f == nil { - return EngineRangeStatus{}, errors.New("missing fuel status") - } - - if f.RangeStatus.Value.PrimaryEngine.Type == typ { - return f.RangeStatus.Value.PrimaryEngine, nil - } - if f.RangeStatus.Value.SecondaryEngine.Type == typ { - return f.RangeStatus.Value.SecondaryEngine, nil - } - - return EngineRangeStatus{}, fmt.Errorf("unknown engine type: %s, got [%s, %s]", typ, f.RangeStatus.Value.PrimaryEngine.Type, f.RangeStatus.Value.SecondaryEngine.Type) -} - -// EngineRangeStatus is the engine range status -type EngineRangeStatus struct { - Type string `json:"type"` - CurrentSOCPct int `json:"currentSOC_pct"` - RemainingRangeKm int `json:"remainingRange_km"` -} - -// ParkingPosition is the /parkingposition api response -type ParkingPosition struct { - Latitude float64 - Longitude float64 - CarCapturedTimestamp Timestamp -} - -// UnmarshalJSON accepts both the latitude/longitude and the shorter lat/lon -// key variants the parkingposition endpoint may return. -func (p *ParkingPosition) UnmarshalJSON(data []byte) error { - var res struct { - Latitude *float64 `json:"latitude"` - Longitude *float64 `json:"longitude"` - Lat *float64 `json:"lat"` - Lon *float64 `json:"lon"` - CarCapturedTimestamp Timestamp `json:"carCapturedTimestamp"` - } - - if err := json.Unmarshal(data, &res); err != nil { - return err - } - - p.CarCapturedTimestamp = res.CarCapturedTimestamp - - switch { - case res.Latitude != nil: - p.Latitude = *res.Latitude - case res.Lat != nil: - p.Latitude = *res.Lat - } - - switch { - case res.Longitude != nil: - p.Longitude = *res.Longitude - case res.Lon != nil: - p.Longitude = *res.Lon - } - - return nil -} - -// Timestamp implements JSON unmarshal -type Timestamp struct { - time.Time -} - -// UnmarshalJSON decodes string timestamp into time.Time -func (ct *Timestamp) UnmarshalJSON(data []byte) error { - s := strings.Trim(string(data), "\"") - - t, err := time.Parse(time.RFC3339, s) - if err == nil { - ct.Time = t - } - - return err -}