Updated config file and config struct
All checks were successful
Golan Testing / testing (1.24.x, ubuntu-latest) (push) Successful in 23s
All checks were successful
Golan Testing / testing (1.24.x, ubuntu-latest) (push) Successful in 23s
This commit is contained in:
395
client.go
395
client.go
@ -13,19 +13,9 @@ import (
|
||||
"resty.dev/v3"
|
||||
)
|
||||
|
||||
// credentials .
|
||||
type credentials struct {
|
||||
username string
|
||||
password string
|
||||
pin string
|
||||
deviceId string
|
||||
deviceName string
|
||||
}
|
||||
|
||||
// Client .
|
||||
type Client struct {
|
||||
baseURL string
|
||||
credentials credentials
|
||||
credentials config.Credentials
|
||||
httpClient *resty.Client
|
||||
country string // USA | CA
|
||||
updateInterval int // 7200
|
||||
@ -38,125 +28,14 @@ type Client struct {
|
||||
sync.RWMutex
|
||||
}
|
||||
|
||||
// Option .
|
||||
type Option func(*Client) error
|
||||
|
||||
// BaseURL allows overriding of API client baseURL for testing
|
||||
func BaseURL(baseURL string) Option {
|
||||
return func(c *Client) error {
|
||||
c.baseURL = baseURL
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// Username .
|
||||
func Username(username string) Option {
|
||||
return func(c *Client) error {
|
||||
c.credentials.username = username
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// Password .
|
||||
func Password(password string) Option {
|
||||
return func(c *Client) error {
|
||||
c.credentials.password = password
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// auth .
|
||||
func (c *Client) auth() []byte {
|
||||
// {
|
||||
// "success": true,
|
||||
// "errorCode": null,
|
||||
// "dataName": "sessionData",
|
||||
// "data": {
|
||||
// "sessionChanged": false,
|
||||
// "vehicleInactivated": false,
|
||||
// "account": {
|
||||
// "marketId": 1,
|
||||
// "createdDate": 1476984644000,
|
||||
// "firstName": "Tatiana",
|
||||
// "lastName": "Savin",
|
||||
// "zipCode": "07974",
|
||||
// "accountKey": 765268,
|
||||
// "lastLoginDate": 1640539132000,
|
||||
// "zipCode5": "07974"
|
||||
// },
|
||||
// "resetPassword": false,
|
||||
// "deviceId": "JddMBQXvAkgutSmEP6uFsThbq4QgEBBQ",
|
||||
// "sessionId": "010A2C0C25A5D35AC3776DB6B7900A3B",
|
||||
// "deviceRegistered": true,
|
||||
// "passwordToken": null,
|
||||
// "vehicles": [
|
||||
// {
|
||||
// "customer": {
|
||||
// "sessionCustomer": null,
|
||||
// "email": null,
|
||||
// "firstName": null,
|
||||
// "lastName": null,
|
||||
// "zip": null,
|
||||
// "oemCustId": null,
|
||||
// "phone": null
|
||||
// },
|
||||
// "stolenVehicle": false,
|
||||
// "vehicleName": "Subaru Outback LXT",
|
||||
// "features": null,
|
||||
// "vin": "4S4BTGND8L3137058",
|
||||
// "modelYear": null,
|
||||
// "modelCode": null,
|
||||
// "engineSize": null,
|
||||
// "nickname": "Subaru Outback LXT",
|
||||
// "vehicleKey": 3832950,
|
||||
// "active": true,
|
||||
// "licensePlate": "",
|
||||
// "licensePlateState": "",
|
||||
// "email": null,
|
||||
// "firstName": null,
|
||||
// "lastName": null,
|
||||
// "subscriptionFeatures": null,
|
||||
// "accessLevel": -1,
|
||||
// "zip": null,
|
||||
// "oemCustId": "CRM-631-HQN48K",
|
||||
// "vehicleMileage": null,
|
||||
// "phone": null,
|
||||
// "userOemCustId": "CRM-631-HQN48K",
|
||||
// "subscriptionStatus": null,
|
||||
// "authorizedVehicle": false,
|
||||
// "preferredDealer": null,
|
||||
// "cachedStateCode": "NJ",
|
||||
// "subscriptionPlans": [],
|
||||
// "needMileagePrompt": false,
|
||||
// "phev": null,
|
||||
// "remoteServicePinExist": true,
|
||||
// "needEmergencyContactPrompt": false,
|
||||
// "vehicleGeoPosition": null,
|
||||
// "extDescrip": null,
|
||||
// "intDescrip": null,
|
||||
// "modelName": null,
|
||||
// "transCode": null,
|
||||
// "provisioned": true,
|
||||
// "timeZone": "America/New_York"
|
||||
// }
|
||||
// ],
|
||||
// "currentVehicleIndex": 0,
|
||||
// "handoffToken": "$2a$08$99me3RRpB00MNMSFxrG7AOg1T5BaDVacqXhbdTii0eRXoEoeFvEPy$1640540934344",
|
||||
// "enableXtime": true,
|
||||
// "termsAndConditionsAccepted": true,
|
||||
// "digitalGlobeConnectId": "0572e32b-2fcf-4bc8-abe0-1e3da8767132",
|
||||
// "digitalGlobeImageTileService": "https://earthwatch.digitalglobe.com/earthservice/tmsaccess/tms/1.0.0/DigitalGlobe:ImageryTileService@EPSG:3857@png/{z}/{x}/{y}.png?connectId=0572e32b-2fcf-4bc8-abe0-1e3da8767132",
|
||||
// "digitalGlobeTransparentTileService": "https://earthwatch.digitalglobe.com/earthservice/tmsaccess/tms/1.0.0/Digitalglobe:OSMTransparentTMSTileService@EPSG:3857@png/{z}/{x}/{-y}.png/?connectId=0572e32b-2fcf-4bc8-abe0-1e3da8767132",
|
||||
// "tomtomKey": "DHH9SwEQ4MW55Hj2TfqMeldbsDjTdgAs",
|
||||
// "satelliteViewEnabled": true
|
||||
// }
|
||||
// }
|
||||
params := map[string]string{
|
||||
"env": "cloudprod",
|
||||
"deviceType": "android",
|
||||
"loginUsername": c.credentials.username,
|
||||
"password": c.credentials.password,
|
||||
"deviceId": c.credentials.deviceId,
|
||||
"loginUsername": c.credentials.Username,
|
||||
"password": c.credentials.Password,
|
||||
"deviceId": c.credentials.DeviceID,
|
||||
"passwordToken": "",
|
||||
"selectedVin": "",
|
||||
"pushToken": ""}
|
||||
@ -195,9 +74,9 @@ func (c *Client) registerDevice() bool {
|
||||
// }).
|
||||
// Post(apiURLs["WEB_API_LOGIN"])
|
||||
params := map[string]string{
|
||||
"username": c.credentials.username,
|
||||
"password": c.credentials.password,
|
||||
"deviceId": c.credentials.deviceId}
|
||||
"username": c.credentials.Username,
|
||||
"password": c.credentials.Password,
|
||||
"deviceId": c.credentials.DeviceID}
|
||||
reqURL := WEB_API_SERVER[c.country] + apiURLs["WEB_API_LOGIN"]
|
||||
c.execute(reqURL, POST, params, "", true)
|
||||
|
||||
@ -210,7 +89,7 @@ func (c *Client) registerDevice() bool {
|
||||
// }).
|
||||
// Get(apiURLs["WEB_API_AUTHORIZE_DEVICE"])
|
||||
params = map[string]string{
|
||||
"deviceId": c.credentials.deviceId}
|
||||
"deviceId": c.credentials.DeviceID}
|
||||
reqURL = WEB_API_SERVER[c.country] + apiURLs["WEB_API_AUTHORIZE_DEVICE"]
|
||||
c.execute(reqURL, GET, params, "", false)
|
||||
|
||||
@ -220,8 +99,8 @@ func (c *Client) registerDevice() bool {
|
||||
// setDeviceName .
|
||||
func (c *Client) setDeviceName() bool {
|
||||
params := map[string]string{
|
||||
"deviceId": c.credentials.deviceId,
|
||||
"deviceName": c.credentials.deviceName}
|
||||
"deviceId": c.credentials.DeviceID,
|
||||
"deviceName": c.credentials.DeviceName}
|
||||
reqURL := WEB_API_SERVER[c.country] + apiURLs["WEB_API_NAME_DEVICE"]
|
||||
c.execute(reqURL, GET, params, "", false)
|
||||
|
||||
@ -315,111 +194,76 @@ func (c *Client) validateSession() bool {
|
||||
// if await self._select_vehicle(vin):
|
||||
// result = True
|
||||
|
||||
c.log.Debug("[DEBUG] Validate Session", "body", string([]byte(resp)))
|
||||
c.log.Debug("session validation", "body", string([]byte(resp)))
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func (c *Client) SelectVehicle(vin string) VehicleData {
|
||||
// {
|
||||
// "success": true,
|
||||
// "errorCode": null,
|
||||
// "dataName": "vehicle",
|
||||
// "data": {
|
||||
// "customer": {
|
||||
// "sessionCustomer": null,
|
||||
// "email": null,
|
||||
// "firstName": null,
|
||||
// "lastName": null,
|
||||
// "zip": null,
|
||||
// "oemCustId": null,
|
||||
// "phone": null
|
||||
// },
|
||||
// "stolenVehicle": false,
|
||||
// "vehicleName": "Subaru Outback LXT",
|
||||
// "features": [
|
||||
// "ATF_MIL",
|
||||
// "11.6MMAN",
|
||||
// "ABS_MIL",
|
||||
// "CEL_MIL",
|
||||
// "ACCS",
|
||||
// "RCC",
|
||||
// "REARBRK",
|
||||
// "TEL_MIL",
|
||||
// "VDC_MIL",
|
||||
// "TPMS_MIL",
|
||||
// "WASH_MIL",
|
||||
// "BSDRCT_MIL",
|
||||
// "OPL_MIL",
|
||||
// "EYESIGHT",
|
||||
// "RAB_MIL",
|
||||
// "SRS_MIL",
|
||||
// "ESS_MIL",
|
||||
// "RESCC",
|
||||
// "EOL_MIL",
|
||||
// "BSD",
|
||||
// "EBD_MIL",
|
||||
// "EPB_MIL",
|
||||
// "RES",
|
||||
// "RHSF",
|
||||
// "AWD_MIL",
|
||||
// "NAV_TOMTOM",
|
||||
// "ISS_MIL",
|
||||
// "RPOIA",
|
||||
// "EPAS_MIL",
|
||||
// "RPOI",
|
||||
// "AHBL_MIL",
|
||||
// "SRH_MIL",
|
||||
// "g2"
|
||||
// ],
|
||||
// "vin": "4S4BTGND8L3137058",
|
||||
// "modelYear": "2020",
|
||||
// "modelCode": "LDJ",
|
||||
// "engineSize": 2.4,
|
||||
// "nickname": "Subaru Outback LXT",
|
||||
// "vehicleKey": 3832950,
|
||||
// "active": true,
|
||||
// "licensePlate": "8KV8",
|
||||
// "licensePlateState": "NJ",
|
||||
// "email": null,
|
||||
// "firstName": null,
|
||||
// "lastName": null,
|
||||
// "subscriptionFeatures": [
|
||||
// "REMOTE",
|
||||
// "SAFETY",
|
||||
// "Retail"
|
||||
// ],
|
||||
// "accessLevel": -1,
|
||||
// "zip": null,
|
||||
// "oemCustId": "CRM-631-HQN48K",
|
||||
// "vehicleMileage": null,
|
||||
// "phone": null,
|
||||
// "userOemCustId": "CRM-631-HQN48K",
|
||||
// "subscriptionStatus": "ACTIVE",
|
||||
// "authorizedVehicle": false,
|
||||
// "preferredDealer": null,
|
||||
// "cachedStateCode": "NJ",
|
||||
// "subscriptionPlans": [],
|
||||
// "needMileagePrompt": false,
|
||||
// "phev": null,
|
||||
// "remoteServicePinExist": true,
|
||||
// "needEmergencyContactPrompt": false,
|
||||
// "vehicleGeoPosition": {
|
||||
// "latitude": 40.70019,
|
||||
// "longitude": -74.401375,
|
||||
// "speed": null,
|
||||
// "heading": null,
|
||||
// "timestamp": 1640494569000
|
||||
// },
|
||||
// "extDescrip": "Abyss Blue Pearl",
|
||||
// "intDescrip": "Gray",
|
||||
// "modelName": "Outback",
|
||||
// "transCode": "CVT",
|
||||
// "provisioned": true,
|
||||
// "timeZone": "America/New_York"
|
||||
// }
|
||||
// }
|
||||
// New function creates a New MySubaru client
|
||||
func New(logger *slog.Logger, config *config.MySubaru) (*Client, error) {
|
||||
|
||||
client := &Client{
|
||||
credentials: config.Credentials,
|
||||
country: config.Region,
|
||||
updateInterval: 7200,
|
||||
fetchInterval: 360,
|
||||
log: logger,
|
||||
}
|
||||
|
||||
httpClient := resty.New()
|
||||
httpClient.
|
||||
SetBaseURL(MOBILE_API_SERVER[client.country]).
|
||||
SetHeaders(map[string]string{
|
||||
"User-Agent": "Mozilla/5.0 (Linux; Android 10; Android SDK built for x86 Build/QSR1.191030.002; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/74.0.3729.185 Mobile Safari/537.36",
|
||||
"Origin": "file://",
|
||||
"X-Requested-With": MOBILE_APP[client.country],
|
||||
"Accept-Language": "en-US,en;q=0.9",
|
||||
"Accept-Encoding": "gzip, deflate",
|
||||
"Accept": "*/*"})
|
||||
|
||||
client.httpClient = httpClient
|
||||
|
||||
resp := client.auth()
|
||||
respParsed, err := gabs.ParseJSON(resp)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if client.isResponseSuccessfull(resp) {
|
||||
logger.Debug("Client authentication successful", "isRegistered", respParsed.Path("data.deviceRegistered").Data().(bool))
|
||||
client.isAuthenticated = true
|
||||
client.isRegistered = respParsed.Path("data.deviceRegistered").Data().(bool)
|
||||
} else {
|
||||
error, _ := respParsed.Path("errorCode").Data().(string)
|
||||
switch {
|
||||
case error == apiErrors["ERROR_INVALID_ACCOUNT"]:
|
||||
logger.Debug("Invalid account")
|
||||
case error == apiErrors["ERROR_INVALID_CREDENTIALS"]:
|
||||
logger.Debug("Client authentication failed")
|
||||
case error == apiErrors["ERROR_PASSWORD_WARNING"]:
|
||||
logger.Debug("Multiple Password Failures.")
|
||||
default:
|
||||
logger.Debug("Uknown error")
|
||||
}
|
||||
}
|
||||
|
||||
if !client.isRegistered {
|
||||
client.registerDevice()
|
||||
}
|
||||
|
||||
// TODO
|
||||
fmt.Printf("Parcing cars: %d\n", len(respParsed.Path("data.vehicles").Children()))
|
||||
for _, vehicle := range respParsed.Path("data.vehicles").Children() {
|
||||
fmt.Printf("CAR: %s\n", vehicle.Path("vin").Data().(string))
|
||||
client.listOfVins = append(client.listOfVins, vehicle.Path("vin").Data().(string))
|
||||
}
|
||||
client.currentVin = respParsed.Path("data.vehicles.0.vin").Data().(string)
|
||||
|
||||
return client, nil
|
||||
}
|
||||
|
||||
func (c *Client) SelectVehicle(vin string) VehicleData {
|
||||
// API > json > dataName > vehicle
|
||||
if vin == "" {
|
||||
vin = c.currentVin
|
||||
}
|
||||
@ -467,78 +311,6 @@ func (c *Client) SelectVehicle(vin string) VehicleData {
|
||||
return vData
|
||||
}
|
||||
|
||||
// New function creates a New MySubaru client
|
||||
func New(logger *slog.Logger, config *config.MySubaru) (*Client, error) {
|
||||
|
||||
credentials := credentials{
|
||||
username: config.Credentials.Username,
|
||||
password: config.Credentials.Password,
|
||||
pin: config.Credentials.PIN,
|
||||
deviceId: config.Credentials.DeviceID,
|
||||
deviceName: config.Credentials.DeviceName,
|
||||
}
|
||||
|
||||
client := &Client{
|
||||
credentials: credentials,
|
||||
country: config.Region,
|
||||
updateInterval: 7200,
|
||||
fetchInterval: 360,
|
||||
log: logger,
|
||||
}
|
||||
|
||||
httpClient := resty.New()
|
||||
httpClient.
|
||||
SetBaseURL(MOBILE_API_SERVER[client.country]).
|
||||
SetHeaders(map[string]string{
|
||||
"User-Agent": "Mozilla/5.0 (Linux; Android 10; Android SDK built for x86 Build/QSR1.191030.002; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/74.0.3729.185 Mobile Safari/537.36",
|
||||
"Origin": "file://",
|
||||
"X-Requested-With": MOBILE_APP[client.country],
|
||||
"Accept-Language": "en-US,en;q=0.9",
|
||||
"Accept-Encoding": "gzip, deflate",
|
||||
"Accept": "*/*"})
|
||||
|
||||
client.httpClient = httpClient
|
||||
|
||||
resp := client.auth()
|
||||
|
||||
respParsed, err := gabs.ParseJSON(resp)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if client.isResponseSuccessfull(resp) {
|
||||
logger.Debug("Client authentication successful", "isRegistered", respParsed.Path("data.deviceRegistered").Data().(bool))
|
||||
client.isAuthenticated = true
|
||||
client.isRegistered = respParsed.Path("data.deviceRegistered").Data().(bool)
|
||||
} else {
|
||||
error, _ := respParsed.Path("errorCode").Data().(string)
|
||||
switch {
|
||||
case error == apiErrors["ERROR_INVALID_ACCOUNT"]:
|
||||
logger.Debug("Invalid account")
|
||||
case error == apiErrors["ERROR_INVALID_CREDENTIALS"]:
|
||||
logger.Debug("Client authentication failed")
|
||||
case error == apiErrors["ERROR_PASSWORD_WARNING"]:
|
||||
logger.Debug("Multiple Password Failures.")
|
||||
default:
|
||||
logger.Debug("Uknown error")
|
||||
}
|
||||
}
|
||||
|
||||
if !client.isRegistered {
|
||||
client.registerDevice()
|
||||
}
|
||||
|
||||
// TODO
|
||||
fmt.Printf("Parcing cars: %d\n", len(respParsed.Path("data.vehicles").Children()))
|
||||
for _, vehicle := range respParsed.Path("data.vehicles").Children() {
|
||||
fmt.Printf("CAR: %s\n", vehicle.Path("vin").Data().(string))
|
||||
client.listOfVins = append(client.listOfVins, vehicle.Path("vin").Data().(string))
|
||||
}
|
||||
client.currentVin = respParsed.Path("data.vehicles.0.vin").Data().(string)
|
||||
|
||||
return client, nil
|
||||
}
|
||||
|
||||
// GetVehicles .
|
||||
func (c *Client) GetVehicles() []*Vehicle {
|
||||
var vehicles []*Vehicle
|
||||
@ -551,7 +323,7 @@ func (c *Client) GetVehicles() []*Vehicle {
|
||||
|
||||
respParsed, err := gabs.ParseJSON([]byte(resp))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
c.log.Error("error which parsing json", "request", "GetVehicles", "error", err.Error())
|
||||
}
|
||||
|
||||
vData := VehicleData{}
|
||||
@ -603,7 +375,7 @@ func (c *Client) GetVehicleByVIN(vin string) *Vehicle {
|
||||
|
||||
respParsed, err := gabs.ParseJSON([]byte(resp))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
c.log.Error("error which parsing json", "request", "GetVehicleByVIN", "error", err.Error())
|
||||
}
|
||||
|
||||
vData := VehicleData{}
|
||||
@ -682,7 +454,7 @@ func (c *Client) GetVehicleStatus() {
|
||||
|
||||
respParsed, err := gabs.ParseJSON(resp)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
c.log.Error("error which parsing json", "request", "GetVehicleStatus", "error", err.Error())
|
||||
}
|
||||
c.log.Debug("GET VEHICLE STATUS OUTPUT", "body", respParsed)
|
||||
|
||||
@ -718,7 +490,7 @@ func (c *Client) GetClimateSettings() {
|
||||
|
||||
respParsed, err := gabs.ParseJSON(resp)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
c.log.Error("error which parsing json", "request", "GetClimateSettings", "error", err.Error())
|
||||
}
|
||||
c.log.Debug("CLIMATE SETTINGS OUTPUT", "response", respParsed)
|
||||
|
||||
@ -755,12 +527,8 @@ func (c *Client) GetClimateSettings() {
|
||||
func (c *Client) execute(requestUrl string, method string, params map[string]string, pollingUrl string, json bool) []byte {
|
||||
defer timeTrack("[TIMETRK] Executing Get Request")
|
||||
|
||||
// if !isNil(resp.Cookies()) {
|
||||
// log.Debugf("AUTH COOKIES OUTPUT >> %v\n", resp.Cookies())
|
||||
// c.cookies = resp.Cookies()
|
||||
// }
|
||||
|
||||
var resp *resty.Response
|
||||
|
||||
// GET Requests
|
||||
if method == "GET" {
|
||||
resp, _ = c.httpClient.
|
||||
@ -791,9 +559,8 @@ func (c *Client) execute(requestUrl string, method string, params map[string]str
|
||||
// }
|
||||
respParsed, err := gabs.ParseJSON(resBytes)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
c.log.Error("error which parsing json", "request", "execute", "method", method, "url", requestUrl, "error", err.Error())
|
||||
}
|
||||
|
||||
c.log.Debug("HTTP OUTPUT", "body", string(resBytes))
|
||||
|
||||
_, ok := respParsed.Path("success").Data().(bool)
|
||||
|
@ -1,20 +1,33 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"log/slog"
|
||||
"os"
|
||||
|
||||
"github.com/spf13/viper"
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
const (
|
||||
LoggingOutputJson = "JSON"
|
||||
LoggingOutputText = "TEXT"
|
||||
)
|
||||
|
||||
// Config .
|
||||
type Config struct {
|
||||
MySubaru MySubaru
|
||||
TimeZone string
|
||||
Logger *slog.Logger
|
||||
}
|
||||
|
||||
// config defines the structure of configuration data to be parsed from a config source.
|
||||
type config struct {
|
||||
MySubaru MySubaru `json:"mysubaru" yaml:"mysubaru"`
|
||||
Timezone string `json:"timezone" yaml:"timezone"`
|
||||
TimeZone string `json:"timezone" yaml:"timezone"`
|
||||
Logging *Logging `json:"logging" yaml:"logging"`
|
||||
}
|
||||
|
||||
// Emporia .
|
||||
// MySubaru .
|
||||
type MySubaru struct {
|
||||
Credentials Credentials `json:"credentials" yaml:"credentials"`
|
||||
Region string `json:"region" yaml:"region"`
|
||||
@ -37,36 +50,49 @@ type Logging struct {
|
||||
Source bool `json:"source,omitempty" yaml:"source,omitempty"`
|
||||
}
|
||||
|
||||
func New() (*Config, error) {
|
||||
viper.SetConfigName("config") // name of config file (without extension)
|
||||
viper.SetConfigType("yaml") // REQUIRED if the config file does not have the extension in the name
|
||||
viper.AddConfigPath(".") // optionally look for config in the working directory
|
||||
viper.AddConfigPath("/etc/mysubaru") // optionally look for config in the working directory
|
||||
|
||||
viper.AutomaticEnv()
|
||||
|
||||
viper.SetDefault("Timezone", "America/New_York")
|
||||
viper.SetDefault("MySubaru.AutoReconnect", true)
|
||||
viper.SetDefault("Logging.Level", "INFO")
|
||||
viper.SetDefault("Logging.Output", "TEXT")
|
||||
viper.SetDefault("Logging.Source", "false")
|
||||
|
||||
err := viper.ReadInConfig() // Find and read the config file
|
||||
if err != nil { // Handle errors reading the config file
|
||||
slog.Error("cannot open config file", "error", err.Error())
|
||||
os.Exit(1)
|
||||
func (l Logging) ToLogger() *slog.Logger {
|
||||
var level slog.Level
|
||||
if err := level.UnmarshalText([]byte(l.Level)); err != nil {
|
||||
level = slog.LevelInfo
|
||||
}
|
||||
|
||||
// viper.WatchConfig()
|
||||
// viper.OnConfigChange(func(e fsnotify.Event) {
|
||||
// log.Println("Config file changed:", e.Name)
|
||||
// })
|
||||
|
||||
var config Config
|
||||
if err := viper.Unmarshal(&config); err != nil {
|
||||
slog.Error("cannot unmarshal config file", "error", err.Error())
|
||||
os.Exit(1)
|
||||
var handler slog.Handler
|
||||
switch l.Output {
|
||||
case LoggingOutputJson:
|
||||
handler = slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{AddSource: l.Source, Level: level})
|
||||
case LoggingOutputText:
|
||||
handler = slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{AddSource: l.Source, Level: level})
|
||||
default:
|
||||
handler = slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{AddSource: l.Source, Level: level})
|
||||
}
|
||||
|
||||
return &config, nil
|
||||
return slog.New(handler)
|
||||
}
|
||||
|
||||
// FromBytes unmarshals a byte slice of JSON or YAML config data into a valid server options value.
|
||||
func FromBytes(b []byte) (*Config, error) {
|
||||
c := new(config)
|
||||
o := Config{}
|
||||
|
||||
if len(b) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
if b[0] == '{' {
|
||||
err := json.Unmarshal(b, c)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
err := yaml.Unmarshal(b, c)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
o.MySubaru = c.MySubaru
|
||||
o.TimeZone = c.TimeZone
|
||||
o.Logger = c.Logging.ToLogger()
|
||||
|
||||
return &o, nil
|
||||
}
|
||||
|
93
config/config_test.go
Normal file
93
config/config_test.go
Normal file
@ -0,0 +1,93 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"log/slog"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
var (
|
||||
yamlBytes = []byte(`
|
||||
mysubaru:
|
||||
credentials:
|
||||
username: username@mysubaru.golang
|
||||
password: "PASSWORD"
|
||||
pin: "1234"
|
||||
deviceid: AaBbCcDdEeFf0123456789
|
||||
devicename: MySubaru Golang Client
|
||||
region: USA
|
||||
auto_reconnect: true
|
||||
timezone: "America/New_York"
|
||||
logging:
|
||||
level: INFO
|
||||
output: TEXT
|
||||
source: false
|
||||
`)
|
||||
|
||||
jsonBytes = []byte(`{
|
||||
"mysubaru": {
|
||||
"credentials": {
|
||||
"username": "username@mysubaru.golang",
|
||||
"password": "PASSWORD",
|
||||
"pin": "1234",
|
||||
"deviceid": "AaBbCcDdEeFf0123456789",
|
||||
"devicename": "MySubaru Golang Client"
|
||||
},
|
||||
"region": "USA",
|
||||
"auto_reconnect": true
|
||||
},
|
||||
"timezone": "America/New_York",
|
||||
"logging": {
|
||||
"level": "INFO",
|
||||
"output": "TEXT",
|
||||
"source": false
|
||||
}
|
||||
}
|
||||
`)
|
||||
parsedOptions = Config{
|
||||
MySubaru: MySubaru{
|
||||
Credentials: Credentials{
|
||||
Username: "username@mysubaru.golang",
|
||||
Password: "PASSWORD",
|
||||
PIN: "1234",
|
||||
DeviceID: "AaBbCcDdEeFf0123456789",
|
||||
DeviceName: "MySubaru Golang Client",
|
||||
},
|
||||
Region: "USA",
|
||||
AutoReconnect: true,
|
||||
},
|
||||
TimeZone: "America/New_York",
|
||||
Logger: slog.New(slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{
|
||||
Level: slog.LevelInfo,
|
||||
})),
|
||||
}
|
||||
)
|
||||
|
||||
func TestFromBytesEmptyL(t *testing.T) {
|
||||
_, err := FromBytes([]byte{})
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestFromBytesYAML(t *testing.T) {
|
||||
o, err := FromBytes(yamlBytes)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, parsedOptions, *o)
|
||||
}
|
||||
|
||||
func TestFromBytesYAMLError(t *testing.T) {
|
||||
_, err := FromBytes(append(yamlBytes, 'a'))
|
||||
require.Error(t, err)
|
||||
}
|
||||
|
||||
func TestFromBytesJSON(t *testing.T) {
|
||||
o, err := FromBytes(jsonBytes)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, parsedOptions, *o)
|
||||
}
|
||||
|
||||
func TestFromBytesJSONError(t *testing.T) {
|
||||
_, err := FromBytes(append(jsonBytes, 'a'))
|
||||
require.Error(t, err)
|
||||
}
|
20
go.mod
20
go.mod
@ -4,23 +4,15 @@ go 1.24
|
||||
|
||||
require (
|
||||
github.com/Jeffail/gabs/v2 v2.7.0
|
||||
github.com/spf13/viper v1.20.1
|
||||
github.com/stretchr/testify v1.10.0
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
resty.dev/v3 v3.0.0-beta.3
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/fsnotify/fsnotify v1.9.0 // indirect
|
||||
github.com/go-viper/mapstructure/v2 v2.2.1 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.2.4 // indirect
|
||||
github.com/sagikazarmark/locafero v0.9.0 // indirect
|
||||
github.com/sourcegraph/conc v0.3.0 // indirect
|
||||
github.com/spf13/afero v1.14.0 // indirect
|
||||
github.com/spf13/cast v1.8.0 // indirect
|
||||
github.com/spf13/pflag v1.0.6 // indirect
|
||||
github.com/subosito/gotenv v1.6.0 // indirect
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/kr/pretty v0.3.1 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
golang.org/x/net v0.40.0 // indirect
|
||||
golang.org/x/sys v0.33.0 // indirect
|
||||
golang.org/x/text v0.25.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect
|
||||
)
|
||||
|
327
vehicle.go
327
vehicle.go
@ -35,67 +35,6 @@ var parts = map[string]map[string][]string{
|
||||
},
|
||||
}
|
||||
|
||||
// {
|
||||
// "success": true,
|
||||
// "errorCode": null,
|
||||
// "dataName": "vehicle",
|
||||
// "data": {
|
||||
// "customer": {
|
||||
// "sessionCustomer": null,
|
||||
// "email": null,
|
||||
// "firstName": null,
|
||||
// "lastName": null,
|
||||
// "zip": null,
|
||||
// "oemCustId": null,
|
||||
// "phone": null
|
||||
// },
|
||||
// "stolenVehicle": false,
|
||||
// "vehicleName": "Subaru Outback LXT",
|
||||
// "features": ["ATF_MIL","11.6MMAN","ABS_MIL","CEL_MIL","ACCS","RCC","REARBRK","TEL_MIL","VDC_MIL","TPMS_MIL","WASH_MIL","BSDRCT_MIL","OPL_MIL","EYESIGHT","RAB_MIL","SRS_MIL","ESS_MIL","RESCC","EOL_MIL","BSD","EBD_MIL","EPB_MIL","RES","RHSF","AWD_MIL","NAV_TOMTOM","ISS_MIL","RPOIA","EPAS_MIL","RPOI","AHBL_MIL","SRH_MIL","g2"],
|
||||
// "vin": "4S4BTGND8L3137058",
|
||||
// "modelYear": "2020",
|
||||
// "modelCode": "LDJ",
|
||||
// "engineSize": 2.4,
|
||||
// "nickname": "Subaru Outback LXT",
|
||||
// "vehicleKey": 3832950,
|
||||
// "active": true,
|
||||
// "licensePlate": "8KV8",
|
||||
// "licensePlateState": "NJ",
|
||||
// "email": null,
|
||||
// "firstName": null,
|
||||
// "lastName": null,
|
||||
// "subscriptionFeatures": ["REMOTE","SAFETY","Retail"],
|
||||
// "accessLevel": -1,
|
||||
// "zip": null,
|
||||
// "oemCustId": "CRM-631-HQN48K",
|
||||
// "vehicleMileage": null,
|
||||
// "phone": null,
|
||||
// "userOemCustId": "CRM-631-HQN48K",
|
||||
// "subscriptionStatus": "ACTIVE",
|
||||
// "authorizedVehicle": false,
|
||||
// "preferredDealer": null,
|
||||
// "cachedStateCode": "NJ",
|
||||
// "subscriptionPlans": [],
|
||||
// "needMileagePrompt": false,
|
||||
// "phev": null,
|
||||
// "remoteServicePinExist": true,
|
||||
// "needEmergencyContactPrompt": false,
|
||||
// "vehicleGeoPosition": {
|
||||
// "latitude": 40.70018,
|
||||
// "longitude": -74.40139,
|
||||
// "speed": null,
|
||||
// "heading": null,
|
||||
// "timestamp": 1642538410000
|
||||
// },
|
||||
// "extDescrip": "Abyss Blue Pearl",
|
||||
// "intDescrip": "Gray",
|
||||
// "modelName": "Outback",
|
||||
// "transCode": "CVT",
|
||||
// "provisioned": true,
|
||||
// "timeZone": "America/New_York"
|
||||
// }
|
||||
// }
|
||||
|
||||
// Vehicle .
|
||||
type Vehicle struct {
|
||||
CarId int64
|
||||
@ -251,49 +190,14 @@ func (v *Vehicle) String() string {
|
||||
}
|
||||
|
||||
// Lock .
|
||||
// Send command to lock doors.
|
||||
// Sends a command to lock doors.
|
||||
func (v *Vehicle) Lock() {
|
||||
// {
|
||||
// "success": true,
|
||||
// "errorCode": null,
|
||||
// "dataName": "remoteServiceStatus",
|
||||
// "data": {
|
||||
// "serviceRequestId": "4S4BTGND8L3137058_1640454085449_20_@NGTP",
|
||||
// "success": false,
|
||||
// "cancelled": false,
|
||||
// "remoteServiceType": "lock",
|
||||
// "remoteServiceState": "started",
|
||||
// "subState": null,
|
||||
// "errorCode": null,
|
||||
// "result": null,
|
||||
// "updateTime": 1640454085000,
|
||||
// "vin": "4S4BTGND8L3137058"
|
||||
// }
|
||||
// }
|
||||
// {
|
||||
// "success": true,
|
||||
// "errorCode": null,
|
||||
// "dataName": "remoteServiceStatus",
|
||||
// "data": {
|
||||
// "serviceRequestId": "4S4BTGND8L3137058_1640454085449_20_@NGTP",
|
||||
// "success": true,
|
||||
// "cancelled": false,
|
||||
// "remoteServiceType": "lock",
|
||||
// "remoteServiceState": "finished",
|
||||
// "subState": null,
|
||||
// "errorCode": "null:null",
|
||||
// "result": null,
|
||||
// "updateTime": 1640454091000,
|
||||
// "vin": "4S4BTGND8L3137058"
|
||||
// }
|
||||
// }
|
||||
|
||||
if v.getRemoteOptionsStatus() {
|
||||
v.selectVehicle()
|
||||
params := map[string]string{
|
||||
"delay": "0",
|
||||
"vin": v.Vin,
|
||||
"pin": v.client.credentials.pin,
|
||||
"pin": v.client.credentials.PIN,
|
||||
"forceKeyInCar": "false"}
|
||||
reqURL := MOBILE_API_VERSION + urlToGen(apiURLs["API_LOCK"], v.getAPIGen())
|
||||
pollingURL := MOBILE_API_VERSION + apiURLs["API_REMOTE_SVC_STATUS"]
|
||||
@ -306,47 +210,12 @@ func (v *Vehicle) Lock() {
|
||||
// Unlock .
|
||||
// Send command to unlock doors.
|
||||
func (v *Vehicle) Unlock() {
|
||||
// {
|
||||
// "success": true,
|
||||
// "errorCode": null,
|
||||
// "dataName": "remoteServiceStatus",
|
||||
// "data": {
|
||||
// "serviceRequestId": "4S4BTGND8L3137058_1640539133289_19_@NGTP",
|
||||
// "success": false,
|
||||
// "cancelled": false,
|
||||
// "remoteServiceType": "unlock",
|
||||
// "remoteServiceState": "started",
|
||||
// "subState": null,
|
||||
// "errorCode": null,
|
||||
// "result": null,
|
||||
// "updateTime": 1640539133000,
|
||||
// "vin": "4S4BTGND8L3137058"
|
||||
// }
|
||||
// }
|
||||
// {
|
||||
// "success": true,
|
||||
// "errorCode": null,
|
||||
// "dataName": "remoteServiceStatus",
|
||||
// "data": {
|
||||
// "serviceRequestId": "4S4BTGND8L3137058_1640539133289_19_@NGTP",
|
||||
// "success": true,
|
||||
// "cancelled": false,
|
||||
// "remoteServiceType": "unlock",
|
||||
// "remoteServiceState": "finished",
|
||||
// "subState": null,
|
||||
// "errorCode": "null:null",
|
||||
// "result": null,
|
||||
// "updateTime": 1640539140000,
|
||||
// "vin": "4S4BTGND8L3137058"
|
||||
// }
|
||||
// }
|
||||
|
||||
if v.getRemoteOptionsStatus() {
|
||||
v.selectVehicle()
|
||||
params := map[string]string{
|
||||
"delay": "0",
|
||||
"vin": v.Vin,
|
||||
"pin": v.client.credentials.pin,
|
||||
"pin": v.client.credentials.PIN,
|
||||
"unlockDoorType": "ALL_DOORS_CMD"} // FRONT_LEFT_DOOR_CMD | ALL_DOORS_CMD
|
||||
reqURL := MOBILE_API_VERSION + urlToGen(apiURLs["API_UNLOCK"], v.getAPIGen())
|
||||
pollingURL := MOBILE_API_VERSION + apiURLs["API_REMOTE_SVC_STATUS"]
|
||||
@ -382,50 +251,15 @@ func (v *Vehicle) Unlock() {
|
||||
// await asyncio.sleep(2)
|
||||
}
|
||||
|
||||
// EngineOn .
|
||||
// Send command to start engine and set climate control.
|
||||
// EngineStart .
|
||||
// Sends a command to start engine and set climate control.
|
||||
func (v *Vehicle) EngineStart() {
|
||||
// {
|
||||
// "success": true,
|
||||
// "errorCode": null,
|
||||
// "dataName": "remoteServiceStatus",
|
||||
// "data": {
|
||||
// "serviceRequestId": "4S4BTGND8L3137058_1640456287656_22_@NGTP",
|
||||
// "success": false,
|
||||
// "cancelled": false,
|
||||
// "remoteServiceType": "engineStart",
|
||||
// "remoteServiceState": "started",
|
||||
// "subState": null,
|
||||
// "errorCode": null,
|
||||
// "result": null,
|
||||
// "updateTime": 1640456287000,
|
||||
// "vin": "4S4BTGND8L3137058"
|
||||
// }
|
||||
// }
|
||||
// {
|
||||
// "success": true,
|
||||
// "errorCode": null,
|
||||
// "dataName": "remoteServiceStatus",
|
||||
// "data": {
|
||||
// "serviceRequestId": "4S4BTGND8L3137058_1640456287656_22_@NGTP",
|
||||
// "success": true,
|
||||
// "cancelled": false,
|
||||
// "remoteServiceType": "engineStart",
|
||||
// "remoteServiceState": "finished",
|
||||
// "subState": null,
|
||||
// "errorCode": "null:null",
|
||||
// "result": null,
|
||||
// "updateTime": 1640456302000,
|
||||
// "vin": "4S4BTGND8L3137058"
|
||||
// }
|
||||
// }
|
||||
|
||||
if v.getRemoteOptionsStatus() {
|
||||
v.selectVehicle()
|
||||
params := map[string]string{
|
||||
"delay": "0",
|
||||
"vin": v.Vin,
|
||||
"pin": v.client.credentials.pin,
|
||||
"pin": v.client.credentials.PIN,
|
||||
"horn": "true",
|
||||
"climateSettings": "climateSettings", // climateSettings
|
||||
"climateZoneFrontTemp": "65", // 60-86
|
||||
@ -447,50 +281,15 @@ func (v *Vehicle) EngineStart() {
|
||||
}
|
||||
}
|
||||
|
||||
// EngineOff .
|
||||
// Send command to stop engine.
|
||||
// EngineStop .
|
||||
// Sends a command to stop engine.
|
||||
func (v *Vehicle) EngineStop() {
|
||||
// {
|
||||
// "success": true,
|
||||
// "errorCode": null,
|
||||
// "dataName": "remoteServiceStatus",
|
||||
// "data": {
|
||||
// "serviceRequestId": "4S4BTGND8L3137058_1640456318773_23_@NGTP",
|
||||
// "success": false,
|
||||
// "cancelled": false,
|
||||
// "remoteServiceType": "engineStop",
|
||||
// "remoteServiceState": "started",
|
||||
// "subState": null,
|
||||
// "errorCode": null,
|
||||
// "result": null,
|
||||
// "updateTime": null,
|
||||
// "vin": "4S4BTGND8L3137058"
|
||||
// }
|
||||
// }
|
||||
// {
|
||||
// "success": true,
|
||||
// "errorCode": null,
|
||||
// "dataName": "remoteServiceStatus",
|
||||
// "data": {
|
||||
// "serviceRequestId": "4S4BTGND8L3137058_1640456318773_23_@NGTP",
|
||||
// "success": true,
|
||||
// "cancelled": false,
|
||||
// "remoteServiceType": "engineStop",
|
||||
// "remoteServiceState": "finished",
|
||||
// "subState": null,
|
||||
// "errorCode": "null:null",
|
||||
// "result": null,
|
||||
// "updateTime": 1640456321000,
|
||||
// "vin": "4S4BTGND8L3137058"
|
||||
// }
|
||||
// }
|
||||
|
||||
if v.getRemoteOptionsStatus() {
|
||||
v.selectVehicle()
|
||||
params := map[string]string{
|
||||
"delay": "0",
|
||||
"vin": v.Vin,
|
||||
"pin": v.client.credentials.pin}
|
||||
"pin": v.client.credentials.PIN}
|
||||
reqURL := MOBILE_API_VERSION + apiURLs["API_G2_REMOTE_ENGINE_STOP"]
|
||||
pollingURL := MOBILE_API_VERSION + apiURLs["API_REMOTE_SVC_STATUS"]
|
||||
v.client.execute(reqURL, POST, params, pollingURL, true)
|
||||
@ -500,49 +299,14 @@ func (v *Vehicle) EngineStop() {
|
||||
}
|
||||
|
||||
// LightsStart .
|
||||
// Send command to flash lights.
|
||||
// Sends a command to flash lights.
|
||||
func (v *Vehicle) LightsStart() {
|
||||
// {
|
||||
// "success": true,
|
||||
// "errorCode": null,
|
||||
// "dataName": "remoteServiceStatus",
|
||||
// "data": {
|
||||
// "serviceRequestId": "4S4BTGND8L3137058_1640457256003_21_@NGTP",
|
||||
// "success": false,
|
||||
// "cancelled": false,
|
||||
// "remoteServiceType": "lightsOnly",
|
||||
// "remoteServiceState": "started",
|
||||
// "subState": null,
|
||||
// "errorCode": null,
|
||||
// "result": null,
|
||||
// "updateTime": 1640457256000,
|
||||
// "vin": "4S4BTGND8L3137058"
|
||||
// }
|
||||
// }
|
||||
// {
|
||||
// "success": true,
|
||||
// "errorCode": null,
|
||||
// "dataName": "remoteServiceStatus",
|
||||
// "data": {
|
||||
// "serviceRequestId": "4S4BTGND8L3137058_1640457256003_21_@NGTP",
|
||||
// "success": true,
|
||||
// "cancelled": false,
|
||||
// "remoteServiceType": "lightsOnly",
|
||||
// "remoteServiceState": "finished",
|
||||
// "subState": null,
|
||||
// "errorCode": "null:null",
|
||||
// "result": null,
|
||||
// "updateTime": 1640457262000,
|
||||
// "vin": "4S4BTGND8L3137058"
|
||||
// }
|
||||
// }
|
||||
|
||||
if v.getRemoteOptionsStatus() {
|
||||
v.selectVehicle()
|
||||
params := map[string]string{
|
||||
"delay": "0",
|
||||
"vin": v.Vin,
|
||||
"pin": v.client.credentials.pin}
|
||||
"pin": v.client.credentials.PIN}
|
||||
reqURL := MOBILE_API_VERSION + urlToGen(apiURLs["API_LIGHTS"], v.getAPIGen())
|
||||
pollingURL := MOBILE_API_VERSION + apiURLs["API_REMOTE_SVC_STATUS"]
|
||||
if v.getAPIGen() == FEATURE_G1_TELEMATICS {
|
||||
@ -555,49 +319,14 @@ func (v *Vehicle) LightsStart() {
|
||||
}
|
||||
|
||||
// LightsStop .
|
||||
// Send command to stop flash lights.
|
||||
// Sends a command to stop flash lights.
|
||||
func (v *Vehicle) LightsStop() {
|
||||
// {
|
||||
// "success": true,
|
||||
// "errorCode": null,
|
||||
// "dataName": "remoteServiceStatus",
|
||||
// "data": {
|
||||
// "serviceRequestId": "4S4BTGND8L3137058_1640457280857_47_@NGTP",
|
||||
// "success": false,
|
||||
// "cancelled": false,
|
||||
// "remoteServiceType": "lightsOnly",
|
||||
// "remoteServiceState": "stopping",
|
||||
// "subState": null,
|
||||
// "errorCode": "null:null",
|
||||
// "result": null,
|
||||
// "updateTime": 1640457262000,
|
||||
// "vin": "4S4BTGND8L3137058"
|
||||
// }
|
||||
// }
|
||||
// {
|
||||
// "success": true,
|
||||
// "errorCode": null,
|
||||
// "dataName": "remoteServiceStatus",
|
||||
// "data": {
|
||||
// "serviceRequestId": "4S4BTGND8L3137058_1640457280857_47_@NGTP",
|
||||
// "success": true,
|
||||
// "cancelled": false,
|
||||
// "remoteServiceType": "lightsOnly",
|
||||
// "remoteServiceState": "finished",
|
||||
// "subState": null,
|
||||
// "errorCode": "null:null",
|
||||
// "result": null,
|
||||
// "updateTime": 1640457280000,
|
||||
// "vin": "4S4BTGND8L3137058"
|
||||
// }
|
||||
// }
|
||||
|
||||
if v.getRemoteOptionsStatus() {
|
||||
v.selectVehicle()
|
||||
params := map[string]string{
|
||||
"delay": "0",
|
||||
"vin": v.Vin,
|
||||
"pin": v.client.credentials.pin}
|
||||
"pin": v.client.credentials.PIN}
|
||||
reqURL := MOBILE_API_VERSION + urlToGen(apiURLs["API_LIGHTS_STOP"], v.getAPIGen())
|
||||
pollingURL := MOBILE_API_VERSION + apiURLs["API_REMOTE_SVC_STATUS"]
|
||||
if v.getAPIGen() == FEATURE_G1_TELEMATICS {
|
||||
@ -617,7 +346,7 @@ func (v *Vehicle) HornStart() {
|
||||
params := map[string]string{
|
||||
"delay": "0",
|
||||
"vin": v.Vin,
|
||||
"pin": v.client.credentials.pin}
|
||||
"pin": v.client.credentials.PIN}
|
||||
reqURL := MOBILE_API_VERSION + urlToGen(apiURLs["API_HORN_LIGHTS"], v.getAPIGen())
|
||||
pollingURL := MOBILE_API_VERSION + apiURLs["API_REMOTE_SVC_STATUS"]
|
||||
if v.getAPIGen() == FEATURE_G1_TELEMATICS {
|
||||
@ -637,7 +366,7 @@ func (v *Vehicle) HornStop() {
|
||||
params := map[string]string{
|
||||
"delay": "0",
|
||||
"vin": v.Vin,
|
||||
"pin": v.client.credentials.pin}
|
||||
"pin": v.client.credentials.PIN}
|
||||
reqURL := MOBILE_API_VERSION + urlToGen(apiURLs["API_HORN_LIGHTS_STOP"], v.getAPIGen())
|
||||
pollingURL := MOBILE_API_VERSION + apiURLs["API_REMOTE_SVC_STATUS"]
|
||||
if v.getAPIGen() == FEATURE_G1_TELEMATICS {
|
||||
@ -691,7 +420,7 @@ func (v *Vehicle) ChargeOn() {
|
||||
params := map[string]string{
|
||||
"delay": "0",
|
||||
"vin": v.Vin,
|
||||
"pin": v.client.credentials.pin}
|
||||
"pin": v.client.credentials.PIN}
|
||||
reqURL := MOBILE_API_VERSION + apiURLs["API_EV_CHARGE_NOW"]
|
||||
pollingURL := MOBILE_API_VERSION + apiURLs["API_REMOTE_SVC_STATUS"]
|
||||
v.client.execute(reqURL, POST, params, pollingURL, true)
|
||||
@ -746,7 +475,7 @@ func (v *Vehicle) GetLocation(force bool) {
|
||||
pollingURL := MOBILE_API_VERSION + apiURLs["API_G2_LOCATE_STATUS"]
|
||||
params := map[string]string{
|
||||
"vin": v.Vin,
|
||||
"pin": v.client.credentials.pin}
|
||||
"pin": v.client.credentials.PIN}
|
||||
if v.getAPIGen() == FEATURE_G1_TELEMATICS {
|
||||
reqURL = MOBILE_API_VERSION + apiURLs["API_G1_LOCATE_UPDATE"]
|
||||
pollingURL = MOBILE_API_VERSION + apiURLs["API_G1_LOCATE_STATUS"]
|
||||
@ -779,7 +508,7 @@ func (v *Vehicle) GetLocation(force bool) {
|
||||
v.selectVehicle()
|
||||
params := map[string]string{
|
||||
"vin": v.Vin,
|
||||
"pin": v.client.credentials.pin}
|
||||
"pin": v.client.credentials.PIN}
|
||||
reqURL := MOBILE_API_VERSION + urlToGen(apiURLs["API_LOCATE"], v.getAPIGen())
|
||||
v.client.execute(reqURL, GET, params, "", false)
|
||||
}
|
||||
@ -790,14 +519,14 @@ func (v *Vehicle) GetClimateQuickPresets() {
|
||||
if v.getRemoteOptionsStatus() {
|
||||
// params := map[string]string{
|
||||
// "vin": v.Vin,
|
||||
// "pin": v.Client.credentials.pin}
|
||||
// "pin": v.Client.credentials.PIN}
|
||||
v.selectVehicle()
|
||||
reqURL := MOBILE_API_VERSION + apiURLs["API_G2_FETCH_RES_QUICK_START_SETTINGS"]
|
||||
resp := v.client.execute(reqURL, GET, map[string]string{}, "", false)
|
||||
|
||||
respParsed, err := gabs.ParseJSON(resp)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
v.client.log.Error("error which parsing json", "request", "GetClimateQuickPresets", "error", err.Error())
|
||||
}
|
||||
v.client.log.Debug("CLIMATE SETTINGS OUTPUT", "body", respParsed)
|
||||
|
||||
@ -826,9 +555,10 @@ func (v *Vehicle) GetClimatePresets() {
|
||||
v.selectVehicle()
|
||||
reqURL := MOBILE_API_VERSION + apiURLs["API_G2_FETCH_RES_SUBARU_PRESETS"]
|
||||
resp := v.client.execute(reqURL, GET, map[string]string{}, "", false)
|
||||
|
||||
respParsed, err := gabs.ParseJSON(resp)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
v.client.log.Error("error which parsing json", "request", "GetClimatePresets", "error", err.Error())
|
||||
}
|
||||
|
||||
// ONLY FOR THAT REQUEST BECAUSE OF API SENDS BACK ESCAPED DATA IN DATA FIELD
|
||||
@ -856,9 +586,10 @@ func (v *Vehicle) GetClimateUserPresets() {
|
||||
v.selectVehicle()
|
||||
reqURL := MOBILE_API_VERSION + apiURLs["API_G2_FETCH_RES_USER_PRESETS"]
|
||||
resp := v.client.execute(reqURL, GET, map[string]string{}, "", false)
|
||||
|
||||
respParsed, err := gabs.ParseJSON(resp)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
v.client.log.Error("error which parsing json", "request", "GetClimateUserPresets", "error", err.Error())
|
||||
}
|
||||
v.client.log.Debug("CLIMATE USER SETTINGS OUTPUT", "body", respParsed)
|
||||
|
||||
@ -904,7 +635,7 @@ func (v *Vehicle) GetVehicleStatus() {
|
||||
if v.client.isResponseSuccessfull(resp) {
|
||||
respParsed, err := gabs.ParseJSON(resp)
|
||||
if err != nil {
|
||||
v.client.log.Error("error which parsing json", "error", err.Error())
|
||||
v.client.log.Error("error which parsing json", "request", "GetVehicleStatus", "error", err.Error())
|
||||
}
|
||||
|
||||
vSta := VehicleStatus{}
|
||||
@ -919,9 +650,7 @@ func (v *Vehicle) GetVehicleStatus() {
|
||||
v.DistanceToEmpty.Kilometers = vSta.DistanceToEmptyFuelKilometers
|
||||
v.DistanceToEmpty.Miles10s = vSta.DistanceToEmptyFuelMiles10s
|
||||
v.DistanceToEmpty.Kilometers10s = vSta.DistanceToEmptyFuelKilometers10s
|
||||
if vSta.RemainingFuelPercent >= 0 && vSta.RemainingFuelPercent <= 100 {
|
||||
v.DistanceToEmpty.Percentage = vSta.RemainingFuelPercent
|
||||
}
|
||||
v.FuelConsumptionAvg.MPG = float64(vSta.AvgFuelConsumptionMpg)
|
||||
v.FuelConsumptionAvg.LP100Km = float64(vSta.AvgFuelConsumptionLitersPer100Kilometers)
|
||||
|
||||
@ -1047,7 +776,7 @@ func (v *Vehicle) GetVehicleStatus() {
|
||||
// }
|
||||
}
|
||||
|
||||
// GetVehicleStatus .
|
||||
// GetVehicleCondition .
|
||||
func (v *Vehicle) GetVehicleCondition() {
|
||||
v.selectVehicle()
|
||||
reqURL := MOBILE_API_VERSION + urlToGen(apiURLs["API_CONDITION"], v.getAPIGen())
|
||||
@ -1056,7 +785,7 @@ func (v *Vehicle) GetVehicleCondition() {
|
||||
if v.client.isResponseSuccessfull(resp) {
|
||||
respParsed, err := gabs.ParseJSON(resp)
|
||||
if err != nil {
|
||||
v.client.log.Error("error which parsing json", "error", err.Error())
|
||||
v.client.log.Error("error which parsing json", "request", "GetVehicleCondition", "error", err.Error())
|
||||
}
|
||||
|
||||
re := regexp.MustCompile(`[A-Z][^A-Z]*`)
|
||||
@ -1166,7 +895,7 @@ func (v *Vehicle) GetVehicleHealth() {
|
||||
if v.client.isResponseSuccessfull(resp) {
|
||||
_, err := gabs.ParseJSON(resp)
|
||||
if err != nil {
|
||||
v.client.log.Error("error which parsing json", "error", err.Error())
|
||||
v.client.log.Error("error which parsing json", "request", "GetVehicleHealth", "error", err.Error())
|
||||
}
|
||||
// TODO:
|
||||
}
|
||||
|
Reference in New Issue
Block a user