Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added AU Region for Saic/MG #17544

Merged
merged 9 commits into from
Dec 4, 2024
Merged
12 changes: 12 additions & 0 deletions templates/definition/vehicle/mg.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,19 @@ params:
de: Erforderlich
en: Required
required: true
- name: region
description:
de: Region
en: Region
# values:
# - EU
# - AU
andig marked this conversation as resolved.
Show resolved Hide resolved
default: EU
advanced: true
render: |
type: mg
{{ include "vehicle-base" . }}
{{ include "vehicle-identify" . }}
{{- if ne .region "EU" }}
region: {{ .region }}
{{- end }}
andig marked this conversation as resolved.
Show resolved Hide resolved
6 changes: 4 additions & 2 deletions vehicle/mg.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,11 @@ func NewMGFromConfig(other map[string]interface{}) (api.Vehicle, error) {
cc := struct {
embed `mapstructure:",squash"`
User, Password, VIN string
Region string
Cache time.Duration
}{
Cache: interval,
Region: "EU",
Cache: interval,
}

if err := util.DecodeOther(other, &cc); err != nil {
Expand All @@ -37,7 +39,7 @@ func NewMGFromConfig(other map[string]interface{}) (api.Vehicle, error) {
}

log := util.NewLogger("mg").Redact(cc.User, cc.Password, cc.VIN)
identity := saic.NewIdentity(log, cc.User, cc.Password)
identity := saic.NewIdentity(log, cc.User, cc.Password, cc.Region)

if err := identity.Login(); err != nil {
return nil, err
Expand Down
31 changes: 20 additions & 11 deletions vehicle/saic/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ func (v *API) printAnswer() {
}
*/

func (v *API) doRepeatedRequest(url string, event_id string) error {
func (v *API) doRepeatedRequest(url string, baseUrl string, event_id string) error {
var req *http.Request

answer := requests.Answer{
Expand All @@ -73,7 +73,9 @@ func (v *API) doRepeatedRequest(url string, event_id string) error {
return err
}

req, err = requests.CreateRequest(url,
req, err = requests.CreateRequest(
url,
baseUrl,
http.MethodGet,
"",
request.JSONContent,
Expand All @@ -94,15 +96,15 @@ func (v *API) doRepeatedRequest(url string, event_id string) error {
}

// This is running concurrently
func (v *API) repeatRequest(url string, event_id string) {
func (v *API) repeatRequest(url string, baseUrl string, event_id string) {
var err error
var count = 0

v.request.Status = StatRunning
for err = api.ErrMustRetry; err == api.ErrMustRetry && count < 20; {
time.Sleep(2 * time.Second)
v.Logger.DEBUG.Printf("Starting repeated query. Count: %d\n", count)
err = v.doRepeatedRequest(url, event_id)
err = v.doRepeatedRequest(url, baseUrl, event_id)
count++
}

Expand Down Expand Up @@ -166,8 +168,11 @@ func (v *API) Wakeup(vin string) error {
return err
}

url := requests.BASE_URL_P + "vehicle/status?vin=" + requests.Sha256(vin)
req, err = requests.CreateRequest(url,
url := v.identity.region.ApiURL + "vehicle/status?vin=" + requests.Sha256(vin)
baseUrl := v.identity.region.ApiURL
req, err = requests.CreateRequest(
url,
baseUrl,
http.MethodGet,
"",
request.JSONContent,
Expand Down Expand Up @@ -210,10 +215,12 @@ func (v *API) Status(vin string) (requests.ChargeStatus, error) {
return res, err
}

url := requests.BASE_URL_P + "vehicle/charging/mgmtData?vin=" + requests.Sha256(vin)

url := v.identity.region.ApiURL + "vehicle/charging/mgmtData?vin=" + requests.Sha256(vin)
baseUrl := v.identity.region.ApiURL
// get charging status of vehicle
req, err = requests.CreateRequest(url,
req, err = requests.CreateRequest(
url,
baseUrl,
http.MethodGet,
"",
request.JSONContent,
Expand All @@ -235,7 +242,9 @@ func (v *API) Status(vin string) (requests.ChargeStatus, error) {
return res, api.ErrMustRetry
}

req, err = requests.CreateRequest(url,
req, err = requests.CreateRequest(
url,
baseUrl,
http.MethodGet,
"",
request.JSONContent,
Expand All @@ -252,7 +261,7 @@ func (v *API) Status(vin string) (requests.ChargeStatus, error) {
if err == api.ErrMustRetry {
v.request.Status = StatRunning
v.Logger.DEBUG.Printf(" No answer yet. Continue status query in background\n")
go v.repeatRequest(url, event_id)
go v.repeatRequest(url, baseUrl, event_id)
} else if err != nil {
v.Logger.ERROR.Printf("doRequest failed with %s", err.Error())
}
Expand Down
8 changes: 6 additions & 2 deletions vehicle/saic/identity.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"fmt"
"net/http"
"net/url"
"strings"
"time"

"github.com/evcc-io/evcc/util"
Expand All @@ -22,14 +23,16 @@ type Identity struct {
User string
Password string
deviceId string
region Region
}

// NewIdentity creates SAIC identity
func NewIdentity(log *util.Logger, user, password string) *Identity {
func NewIdentity(log *util.Logger, user, password string, region string) *Identity {
v := &Identity{
Helper: request.NewHelper(log),
User: user,
Password: requests.Sha1(password),
region: regions[strings.ToUpper(region)],
}

v.deviceId = lo.RandomString(64, lo.AlphanumericCharset) + "###com.saicmotor.europecar"
Expand Down Expand Up @@ -74,7 +77,8 @@ func (v *Identity) retrieveToken(data url.Values) (*oauth2.Token, error) {

// get charging status of vehicle
req, err := requests.CreateRequest(
requests.BASE_URL_P+"oauth/token",
v.region.ApiURL+"oauth/token",
v.region.ApiURL,
http.MethodPost,
data.Encode(),
request.FormContent,
Expand Down
16 changes: 16 additions & 0 deletions vehicle/saic/param.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package saic

type (
Region struct {
ApiURL string
}
)

var regions = map[string]Region{
"EU": {
"https://gateway-mg-eu.soimt.com/api.app/v1/",
},
"AU": {
"https://gateway-mg-au.soimt.com/api.app/v1/",
},
}
1 change: 0 additions & 1 deletion vehicle/saic/requests/api_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,4 @@ const (
PARAM_AUTHENTICATION = "Basic c3dvcmQ6c3dvcmRfc2VjcmV0"
TENANT_ID = "459771"
USER_TYPE = "app"
BASE_URL_P = "https://gateway-mg-eu.soimt.com/api.app/v1/"
)
8 changes: 4 additions & 4 deletions vehicle/saic/requests/encryption.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,12 @@ func CalculateResponseVerification(str, str2, str3 string) string {
return HmacSha256(a4, str5)
}

func EncryptRequest(url string, time int64, tenant, token, body, contentType string) string {
func EncryptRequest(url string, baseUrl string, time int64, tenant, token, body, contentType string) string {
sendDate := strconv.FormatInt(time, 10)
// tenant
replace := ""
if len(url) != 0 {
replace = strings.Replace(url, BASE_URL_P, "/", -1)
replace = strings.Replace(url, baseUrl, "/", -1)
}

encryptedBody := ""
Expand All @@ -70,9 +70,9 @@ func EncryptRequest(url string, time int64, tenant, token, body, contentType str
return encryptedBody
}

func DecryptRequest(url string, time int64, tenant, token, body, contentType string) string {
func DecryptRequest(url string, baseUrl string, time int64, tenant, token, body, contentType string) string {
timeStamp := strconv.FormatInt(time, 10)
resourcePath := strings.Replace(url, BASE_URL_P, "/", -1)
resourcePath := strings.Replace(url, baseUrl, "/", -1)
if len(body) != 0 {
sb3 := Md5(resourcePath+tenant+token+USER_TYPE) + timeStamp + CONTENT_ENCRYPTED + contentType
a2 := Md5(sb3)
Expand Down
4 changes: 3 additions & 1 deletion vehicle/saic/requests/sendRequest.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ func Decorate(req *http.Request) error {

func CreateRequest(
endpoint string,
baseUrl string,
httpMethod string,
request string,
contentType string,
Expand All @@ -32,6 +33,7 @@ func CreateRequest(
if len(request) != 0 {
request = EncryptRequest(
endpoint,
baseUrl,
appSendDate,
TENANT_ID,
token,
Expand All @@ -56,7 +58,7 @@ func CreateRequest(
req.Header.Set("event-id", eventId)
}

replace := strings.Replace(endpoint, BASE_URL_P, "/", -1)
replace := strings.Replace(endpoint, baseUrl, "/", -1)

req.Header.Set("app-verification-string",
CalculateRequestVerification(
Expand Down