Beta version
All checks were successful
Golan Testing / testing (1.24.x, ubuntu-latest) (push) Successful in 24s

This commit is contained in:
2025-06-04 12:58:49 -04:00
parent 934f1259d0
commit c353651287
4 changed files with 63 additions and 109 deletions

View File

@ -4,6 +4,7 @@ import (
"encoding/json"
"io"
"log/slog"
"slices"
"sync"
"time"
@ -60,11 +61,11 @@ func New(config *config.Config) (*Client, error) {
// client.logger.Debug("unmarshaled json data", "request", "auth", "type", "sessionData", "body", sd)
if sd.DeviceRegistered && sd.RegisteredDevicePermanent {
client.logger.Debug("client authentication successful")
// client.logger.Debug("client authentication successful")
client.isAuthenticated = true
client.isRegistered = true
} else {
client.logger.Debug("client authentication successful, but devices is not registered")
// client.logger.Debug("client authentication successful, but devices is not registered")
client.registerDevice()
}
@ -140,7 +141,7 @@ func (c *Client) GetVehicles() []*Vehicle {
// GetVehicleByVIN .
func (c *Client) GetVehicleByVIN(vin string) *Vehicle {
var vehicle *Vehicle
if contains(c.listOfVins, vin) {
if slices.Contains(c.listOfVins, vin) {
params := map[string]string{
"vin": vin,
"_": timestamp()}
@ -212,7 +213,7 @@ func (c *Client) GetVehicleByVIN(vin string) *Vehicle {
// Exec method executes a Client instance with the API URL
func (c *Client) execute(requestUrl string, method string, params map[string]string, pollingUrl string, j bool, attempts ...int) []byte {
defer timeTrack("[TIMETRK] Executing HTTP Request")
// defer timeTrack("[TIMETRK] Executing HTTP Request")
var resp *resty.Response
// GET Requests
@ -290,35 +291,6 @@ func (c *Client) execute(requestUrl string, method string, params map[string]str
return resBytes
}
// // isResponseSuccessfull .
// func (c *Client) isResponseSuccessfull(resp []byte) bool {
// respParsed, err := gabs.ParseJSON(resp)
// if err != nil {
// c.logger.Debug("error while parsing json response", "error", err)
// }
// success, ok := respParsed.Path("success").Data().(bool)
// if !ok {
// c.logger.Debug("response is not successful", "error", resp)
// }
// // ERRORS FROM CLIENT CREATION AFTER AUTH
// // error, _ := respParsed.Path("errorCode").Data().(string)
// // switch {
// // case error == apiErrors["ERROR_INVALID_ACCOUNT"]:
// // fmt.Println("Invalid account")
// // case error == apiErrors["ERROR_INVALID_CREDENTIALS"]:
// // {"success":false,"errorCode":"InvalidCredentials","dataName":"remoteServiceStatus","data":{"serviceRequestId":null,"success":false,"cancelled":false,"remoteServiceType":null,"remoteServiceState":null,"subState":null,"errorCode":null,"result":null,"updateTime":null,"vin":null,"errorDescription":"The credentials supplied are invalid, tries left 2"}}
// // fmt.Println("Client authentication failed")
// // case error == apiErrors["ERROR_PASSWORD_WARNING"]:
// // fmt.Println("Multiple Password Failures.")
// // default:
// // fmt.Println("Uknown error")
// // }
// return success
// }
// auth .
func (c *Client) auth() []byte {
params := map[string]string{
@ -347,46 +319,28 @@ func (c *Client) parseResponse(b []byte) (Response, bool) {
}
// validateSession .
func (c *Client) validateSession() bool {
// {
// "success": true,
// "errorCode": null,
// "dataName": null,
// "data": null
// }
reqURL := MOBILE_API_VERSION + apiURLs["API_VALIDATE_SESSION"]
resp := c.execute(reqURL, GET, map[string]string{}, "", false)
c.logger.Debug("http request output", "request", "validateSession", "body", resp)
// func (c *Client) validateSession() bool {
// // {
// // "success": true,
// // "errorCode": null,
// // "dataName": null,
// // "data": null
// // }
// reqURL := MOBILE_API_VERSION + apiURLs["API_VALIDATE_SESSION"]
// resp := c.execute(reqURL, GET, map[string]string{}, "", false)
// c.logger.Debug("http request output", "request", "validateSession", "body", resp)
var r Response
err := json.Unmarshal(resp, &r)
if err != nil {
c.logger.Error("error while parsing json", "request", "validateSession", "error", err.Error())
}
// var r Response
// err := json.Unmarshal(resp, &r)
// if err != nil {
// c.logger.Error("error while parsing json", "request", "validateSession", "error", err.Error())
// }
if r.Success {
return true
}
return false
// result = False
// js_resp = await self.__open(API_VALIDATE_SESSION, GET)
// _LOGGER.debug(pprint.pformat(js_resp))
// if js_resp["success"]:
// if vin != self._current_vin:
// # API call for VIN that is not the current remote context.
// _LOGGER.debug("Switching Subaru API vehicle context to: %s", vin)
// if await self._select_vehicle(vin):
// result = True
// else:
// result = True
// if result is False:
// await self._authenticate(vin)
// # New session cookie. Must call selectVehicle.json before any other API call.
// if await self._select_vehicle(vin):
// result = True
}
// if r.Success {
// return true
// }
// return false
// }
// GET
// https://www.mysubaru.com/profile/verifyDeviceName.json?clientId=2574212&deviceName=Alex%20Google%20Pixel%204%20XL

View File

@ -281,6 +281,7 @@ type ServiceRequest struct {
// "dataName":"errorResponse"
// {"success":false,"errorCode":"404-soa-unableToParseResponseBody","dataName":"errorResponse","data":{"errorLabel":"404-soa-unableToParseResponseBody","errorDescription":null}}
// {"success":false,"errorCode":"vehicleNotInAccount","dataName":null,"data":null}
// {"success":false,"errorCode":"InvalidCredentials","dataName":"remoteServiceStatus","data":{"serviceRequestId":null,"success":false,"cancelled":false,"remoteServiceType":null,"remoteServiceState":null,"subState":null,"errorCode":null,"result":null,"updateTime":null,"vin":null,"errorDescription":"The credentials supplied are invalid, tries left 2"}}
type ErrorResponse struct {
ErrorLabel string `json:"errorLabel"` // "404-soa-unableToParseResponseBody"
ErrorDescription string `json:"errorDescription,omitempty"` // null

View File

@ -1,7 +1,6 @@
package mysubaru
import (
"fmt"
"math"
"regexp"
"strconv"
@ -9,6 +8,23 @@ import (
"time"
)
// timestamp is a function
func timestamp() string {
return strconv.FormatInt(time.Now().UnixNano()/1000000, 10)
}
// urlToGen .
func urlToGen(url string, gen string) string {
var re = regexp.MustCompile(`api_gen`)
// dirty trick for current G3
if gen == "g3" {
gen = "g2"
}
url = re.ReplaceAllString(url, gen)
return url
}
// VinCheck - Vehicle Identification Number check digit validation
// Parameter: string - 17 digit VIN
// Return:
@ -110,34 +126,17 @@ func transcodeDigits(vin string) int {
// }
// timeTrack .
func timeTrack(name string) {
start := time.Now()
fmt.Printf("%s took %v\n", name, time.Since(start))
}
// timestamp is a function
func timestamp() string {
return strconv.FormatInt(time.Now().UnixNano()/1000000, 10)
}
// func timeTrack(name string) {
// start := time.Now()
// fmt.Printf("%s took %v\n", name, time.Since(start))
// }
// contains .
func contains(s []string, str string) bool {
for _, v := range s {
if v == str {
return true
}
}
return false
}
// urlToGen .
func urlToGen(url string, gen string) string {
var re = regexp.MustCompile(`api_gen`)
// dirty trick for current G3
if gen == "g3" {
gen = "g2"
}
url = re.ReplaceAllString(url, gen)
return url
}
// func contains(s []string, str string) bool {
// for _, v := range s {
// if v == str {
// return true
// }
// }
// return false
// }

View File

@ -759,13 +759,13 @@ func (v *Vehicle) selectVehicle() {
// getAPIGen
// Get the Subaru telematics API generation of a specified VIN
func (v *Vehicle) getAPIGen() string {
if contains(v.Features, FEATURE_G1_TELEMATICS) {
if slices.Contains(v.Features, FEATURE_G1_TELEMATICS) {
return "g1"
}
if contains(v.Features, FEATURE_G2_TELEMATICS) {
if slices.Contains(v.Features, FEATURE_G2_TELEMATICS) {
return "g2"
}
if contains(v.Features, FEATURE_G3_TELEMATICS) {
if slices.Contains(v.Features, FEATURE_G3_TELEMATICS) {
return "g3"
}
return "unknown"
@ -780,13 +780,13 @@ func (v *Vehicle) getAPIGen() string {
// isEV .
// Get whether the specified car is an Electric Vehicle.
func (v *Vehicle) isEV() bool {
return contains(v.Features, FEATURE_PHEV)
return slices.Contains(v.Features, FEATURE_PHEV)
}
// getRemoteOptionsStatus .
// Get whether the specified VIN has remote locks/horn/light service available
func (v *Vehicle) getRemoteOptionsStatus() bool {
return contains(v.SubscriptionFeatures, FEATURE_REMOTE)
return slices.Contains(v.SubscriptionFeatures, FEATURE_REMOTE)
}
// parseDoor .
@ -927,19 +927,19 @@ func (v *Vehicle) parseTire(prefix, suffix, name string, value any) {
// // getRemoteStartStatus .
// // Get whether the specified VIN has remote engine start service available.
// func (v *Vehicle) getRemoteStartStatus() bool {
// return contains(v.Features, FEATURE_REMOTE_START)
// return slices.Contains(v.Features, FEATURE_REMOTE_START)
// }
// // getSafetyStatus .
// // Get whether the specified VIN is has an active Starlink Safety Plus service plan.
// func (v *Vehicle) getSafetyStatus() bool {
// return contains(v.SubscriptionFeatures, FEATURE_SAFETY)
// return slices.Contains(v.SubscriptionFeatures, FEATURE_SAFETY)
// }
// // getSubscriptionStatus .
// // Get whether the specified VIN has an active service plan.
// func (v *Vehicle) getSubscriptionStatus() bool {
// return contains(v.SubscriptionFeatures, FEATURE_ACTIVE)
// return slices.Contains(v.SubscriptionFeatures, FEATURE_ACTIVE)
// }
// // getVehicleName .