-
Notifications
You must be signed in to change notification settings - Fork 1
/
autoiso_api_service.go
240 lines (226 loc) · 7.43 KB
/
autoiso_api_service.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
//nolint:tagliatelle
package gateways
import (
"crypto/md5"
"encoding/hex"
"encoding/json"
"fmt"
"strconv"
"strings"
"time"
"github.com/DIMO-Network/device-definitions-api/internal/config"
"github.com/DIMO-Network/shared"
)
//go:generate mockgen -source autoiso_api_service.go -destination mocks/autoiso_api_service_mock.go -package mocks
type AutoIsoAPIService interface {
GetVIN(vin string) (*AutoIsoVINResponse, error)
}
type autoIsoAPIService struct {
Settings *config.Settings
httpClientVIN shared.HTTPClientWrapper
}
func NewAutoIsoAPIService(settings *config.Settings) AutoIsoAPIService {
if settings.AutoIsoAPIUid == "" || settings.AutoIsoAPIKey == "" {
panic("Drivly configuration not set")
}
hcwv, _ := shared.NewHTTPClientWrapper("http://bp.autoiso.pl", "", 10*time.Second, nil, false)
return &autoIsoAPIService{
Settings: settings,
httpClientVIN: hcwv,
}
}
func (ai *autoIsoAPIService) GetVIN(vin string) (*AutoIsoVINResponse, error) {
input := ai.Settings.AutoIsoAPIUid + ai.Settings.AutoIsoAPIKey + vin
// has with md5
hasher := md5.New()
hasher.Write([]byte(input))
hashedBytes := hasher.Sum(nil)
hashedChecksum := hex.EncodeToString(hashedBytes)
res, err := executeAPI(ai.httpClientVIN, fmt.Sprintf("/api/v3/getSimpleDecoder/apiuid:DIMOZ/checksum:%s/vin:%s", hashedChecksum, vin))
if err != nil {
return nil, err
}
v := &AutoIsoVINResponse{}
err = json.Unmarshal(res, v)
if err != nil {
return nil, err
}
// get percent match from autoiso, if below 50 return err - kinda of an experiment for now
percentMatchStr := strings.TrimSuffix(v.FunctionResponse.Data.API.DataMatching, "%")
percentMatch, _ := strconv.ParseFloat(percentMatchStr, 64)
if percentMatch < 55.0 {
return nil, fmt.Errorf("decode failed due to low DataMatching percent: %f. MMY: %s %s %s", percentMatch,
v.FunctionResponse.Data.Decoder.Make.Value, v.FunctionResponse.Data.Decoder.Model.Value, v.FunctionResponse.Data.Decoder.ModelYear.Value)
}
if v.FunctionResponse.Data.Decoder.ModelYear.Value == "0" || len(v.FunctionResponse.Data.Decoder.ModelYear.Value) == 0 ||
len(v.FunctionResponse.Data.Decoder.Model.Value) == 0 || len(v.FunctionResponse.Data.Decoder.Make.Value) == 0 {
return nil, fmt.Errorf("decode failed due to invalid MMY")
}
return v, nil
}
type AutoIsoVINResponse struct {
Version string `json:"version"`
Vin string `json:"vin"`
APIStatus string `json:"apiStatus"`
ResponseDate string `json:"responseDate"`
FunctionName string `json:"functionName"`
FunctionResponse struct {
Data struct {
API struct {
CoreVersion string `json:"core_version"`
EndpointVersion int `json:"endpoint_version"`
JSONVersion string `json:"json_version"`
APIType string `json:"api_type"`
APICache string `json:"api_cache"`
DataPrecision int `json:"data_precision"`
DataMatching string `json:"data_matching"`
LexLang string `json:"lex_lang"`
} `json:"api"`
Analyze struct {
VinOrginal struct {
Desc string `json:"desc"`
Value string `json:"value"`
} `json:"vin_orginal"`
VinCorrected struct {
Desc string `json:"desc"`
Value string `json:"value"`
} `json:"vin_corrected"`
VinYear struct {
Desc string `json:"desc"`
Value string `json:"value"`
} `json:"vin_year"`
VinSerial struct {
Desc string `json:"desc"`
Value string `json:"value"`
} `json:"vin_serial"`
Checkdigit struct {
Desc string `json:"desc"`
Value string `json:"value"`
} `json:"checkdigit"`
} `json:"analyze"`
Decoder struct {
Make struct {
Desc string `json:"desc"`
Value string `json:"value"`
} `json:"make"`
Model struct {
Desc string `json:"desc"`
Value string `json:"value"`
} `json:"model"`
ModelYear struct {
Desc string `json:"desc"`
Value string `json:"value"`
} `json:"model_year"`
Body struct {
Desc string `json:"desc"`
Value string `json:"value"`
} `json:"body"`
FuelType struct {
Desc string `json:"desc"`
Value string `json:"value"`
} `json:"fuel_type"`
VehicleType struct {
Desc string `json:"desc"`
Value string `json:"value"`
} `json:"vehicle_type"`
Doors struct {
Desc string `json:"desc"`
Value string `json:"value"`
} `json:"doors"`
EngineDisplCm3 struct {
Desc string `json:"desc"`
Value string `json:"value"`
} `json:"engine_displ_cm3"`
EngineDisplL struct {
Desc string `json:"desc"`
Value string `json:"value"`
} `json:"engine_displ_l"`
EnginePowerHp struct {
Desc string `json:"desc"`
Value string `json:"value"`
} `json:"engine_power_hp"`
EnginePowerKw struct {
Desc string `json:"desc"`
Value string `json:"value"`
} `json:"engine_power_kw"`
EngineConf struct {
Desc string `json:"desc"`
Value string `json:"value"`
} `json:"engine_conf"`
EngineType struct {
Desc string `json:"desc"`
Value string `json:"value"`
} `json:"engine_type"`
EngineVersion struct {
Desc string `json:"desc"`
Value string `json:"value"`
} `json:"engine_version"`
EngineHead struct {
Desc string `json:"desc"`
Value string `json:"value"`
} `json:"engine_head"`
EngineValves struct {
Desc string `json:"desc"`
Value string `json:"value"`
} `json:"engine_valves"`
EngineCylinders struct {
Desc string `json:"desc"`
Value string `json:"value"`
} `json:"engine_cylinders"`
EngineDisplCid struct {
Desc string `json:"desc"`
Value string `json:"value"`
} `json:"engine_displ_cid"`
EngineTurbo struct {
Desc string `json:"desc"`
Value string `json:"value"`
} `json:"engine_turbo"`
DriveType struct {
Desc string `json:"desc"`
Value string `json:"value"`
} `json:"drive_type"`
GearboxType struct {
Desc string `json:"desc"`
Value string `json:"value"`
} `json:"gearbox_type"`
EmissionStd struct {
Desc string `json:"desc"`
Value string `json:"value"`
Co2Gkm string `json:"co2_gkm"`
} `json:"emission_std"`
} `json:"decoder"`
} `json:"data"`
} `json:"functionResponse"`
LicenseInfo struct {
LicenseNumber string `json:"licenseNumber"`
ValidTo string `json:"validTo"`
RemainingCredits int `json:"remainingCredits"`
RemainingMonthlyLimit int `json:"remainingMonthlyLimit"`
RemainingDailyLimit int `json:"remainingDailyLimit"`
} `json:"licenseInfo"`
}
// GetStyle returns a standard style string built from the data we have
func (v *AutoIsoVINResponse) GetStyle() string {
s := ""
// eg. Diesel
if len(v.FunctionResponse.Data.Decoder.FuelType.Value) > 0 {
s += v.FunctionResponse.Data.Decoder.FuelType.Value + " "
}
// eg. TDI
if len(v.FunctionResponse.Data.Decoder.EngineVersion.Value) > 0 {
s += v.FunctionResponse.Data.Decoder.EngineVersion.Value + " "
}
// eg. Manual
if len(v.FunctionResponse.Data.Decoder.GearboxType.Value) > 0 {
s += v.FunctionResponse.Data.Decoder.GearboxType.Value + " "
}
// eg. FWD / AWD
if len(v.FunctionResponse.Data.Decoder.DriveType.Value) > 0 {
s += v.FunctionResponse.Data.Decoder.DriveType.Value + " "
}
return strings.TrimSpace(s)
}
// GetSubModel returns the Body type, which we can use as the sub model.
func (v *AutoIsoVINResponse) GetSubModel() string {
return strings.TrimSpace(v.FunctionResponse.Data.Decoder.Body.Value)
}