Skip to content

Commit 0b8cc32

Browse files
authored
Intg-1845 VIN decoding adjustments (#298)
* tweaks to decoding logic, remove old stuff, logging * reorder decoders, add logging * remove deprecated code * update tests * remove unused file
1 parent f1db276 commit 0b8cc32

7 files changed

Lines changed: 35 additions & 236 deletions

File tree

internal/api/common/behaviors.go

Lines changed: 0 additions & 92 deletions
This file was deleted.

internal/api/handlers/device_definition_handler.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
package handlers
22

33
import (
4-
"github.com/tidwall/sjson"
54
"strconv"
65
"strings"
76

7+
"github.com/tidwall/sjson"
8+
89
"github.com/DIMO-Network/device-definitions-api/internal/api/common"
910

1011
p_grpc "github.com/DIMO-Network/device-definitions-api/pkg/grpc"

internal/core/queries/decode_vin.go

Lines changed: 9 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import (
66
"database/sql"
77
"fmt"
88
"strconv"
9-
"strings"
109
"time"
1110

1211
"github.com/tidwall/sjson"
@@ -45,11 +44,10 @@ type DecodeVINQueryHandler struct {
4544
}
4645

4746
type DecodeVINQuery struct {
48-
VIN string `json:"vin"`
49-
KnownModel string `json:"knownModel"`
50-
KnownYear int32 `json:"knownYear"`
51-
Country string `json:"country"`
52-
DefinitionID string `json:"definition_id"`
47+
VIN string `json:"vin"`
48+
KnownModel string `json:"knownModel"`
49+
KnownYear int32 `json:"knownYear"`
50+
Country string `json:"country"`
5351
}
5452

5553
func (*DecodeVINQuery) Key() string { return "DecodeVINQuery" }
@@ -93,11 +91,10 @@ func (dc DecodeVINQueryHandler) Handle(ctx context.Context, query mediator.Messa
9391
Logger()
9492

9593
const (
96-
VinRequests = "VIN_All_Request"
97-
VinSuccess = "VIN_Success_Request"
98-
VinExists = "VIN_Exists_Request"
99-
VinErrors = "VIN_Error_Request"
100-
DeviceDefinitionOverride = "Device_Definition_Override"
94+
VinRequests = "VIN_All_Request"
95+
VinSuccess = "VIN_Success_Request"
96+
VinExists = "VIN_Exists_Request"
97+
VinErrors = "VIN_Error_Request"
10198
)
10299

103100
metrics.Success.With(prometheus.Labels{"method": VinRequests}).Inc()
@@ -119,72 +116,7 @@ func (dc DecodeVINQueryHandler) Handle(ctx context.Context, query mediator.Messa
119116
return r, nil
120117
}
121118

122-
// todo: this should be a separate specific gRPC endpoint for setting or updating vin number to DD mapping
123-
// If DefinitionID passed in, override VIN decoding
124-
localLog.Info().Msgf("Start Decode VIN for vin %s and device definition %s", vin.String(), qry.DefinitionID)
125-
if len(qry.DefinitionID) > 0 {
126-
tblDef, _, err := dc.deviceDefinitionOnChainService.GetDefinitionByID(ctx, qry.DefinitionID)
127-
if err != nil {
128-
return nil, errors.Wrapf(err, "failed to get device definition id: %s", qry.DefinitionID)
129-
}
130-
makeSlug := strings.Split(tblDef.ID, "_")[0]
131-
dm, err := dc.identity.GetManufacturer(makeSlug)
132-
if err != nil {
133-
return nil, errors.Wrapf(err, "failed to get device make for: %s", qry.DefinitionID)
134-
}
135-
dbWMI, err := dc.vinRepository.GetOrCreateWMI(ctx, wmi, dm.Name)
136-
if err != nil {
137-
metrics.InternalError.With(prometheus.Labels{"method": VinErrors}).Inc()
138-
localLog.Error().Err(err).Msgf("failed to get or create wmi for vin %s", vin.String())
139-
return resp, nil
140-
}
141-
142-
// insert vin_numbers
143-
vinDecodeNumber = &models.VinNumber{
144-
Vin: vin.String(),
145-
ManufacturerName: dm.Name,
146-
Wmi: null.StringFrom(dbWMI.Wmi),
147-
VDS: null.StringFrom(vin.VDS()),
148-
Vis: null.StringFrom(vin.VIS()),
149-
CheckDigit: null.StringFrom(vin.CheckDigit()),
150-
SerialNumber: vin.SerialNumber(),
151-
DecodeProvider: null.StringFrom("manual"),
152-
Year: tblDef.Year,
153-
DefinitionID: tblDef.ID,
154-
}
155-
156-
split := strings.Split(vinDecodeNumber.DefinitionID, "_")
157-
if len(split) != 3 {
158-
return nil, errors.New("invalid definition ID encountered: " + vinDecodeNumber.DefinitionID)
159-
}
160-
161-
// no style, maybe for future way to pick the Style from Admin
162-
163-
// note we use a transaction here all throughout and commit at the end
164-
if err = vinDecodeNumber.Insert(ctx, txVinNumbers, boil.Infer()); err != nil {
165-
localLog.Err(err).
166-
Str("definition_id", tblDef.ID).
167-
Msg("failed to insert to vin_numbers")
168-
}
169-
err = txVinNumbers.Commit()
170-
if err != nil {
171-
return nil, errors.Wrap(err, "error when commiting transaction for inserting vin_number")
172-
}
173-
174-
resp.Manufacturer = dm.Name
175-
resp.Year = int32(vinDecodeNumber.Year)
176-
resp.Source = vinDecodeNumber.DecodeProvider.String
177-
pt, err := dc.powerTrainTypeService.ResolvePowerTrainType(split[0], split[1], null.JSON{}, null.JSON{})
178-
if err != nil {
179-
pt = coremodels.ICE.String()
180-
}
181-
resp.Powertrain = pt
182-
resp.DefinitionId = tblDef.ID
183-
184-
metrics.Success.With(prometheus.Labels{"method": DeviceDefinitionOverride}).Inc()
185-
186-
return resp, nil
187-
}
119+
localLog.Info().Msgf("Start Decode VIN ")
188120

189121
_, err = models.DeviceTypes(models.DeviceTypeWhere.ID.EQ(common.DefaultDeviceType)).One(ctx, dc.dbs().Reader)
190122
if err != nil {

internal/core/queries/get_vin_profile.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,11 @@ import (
55
"context"
66
"database/sql"
77
"fmt"
8+
"strings"
9+
810
coremodels "github.com/DIMO-Network/device-definitions-api/internal/core/models"
911
"github.com/DIMO-Network/device-definitions-api/internal/core/services"
1012
"github.com/DIMO-Network/shared/pkg/logfields"
11-
"strings"
1213

1314
"github.com/DIMO-Network/device-definitions-api/internal/core/mediator"
1415
"github.com/DIMO-Network/device-definitions-api/internal/infrastructure/db/models"

internal/core/services/vin_decoding_service.go

Lines changed: 18 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ func (c vinDecodingService) GetVIN(ctx context.Context, vin string, provider cor
7979
if len(providersToTry) == 0 {
8080
if provider == coremodels.AllProviders {
8181
// fill in the list, future could do something country specific
82-
providersToTry = append(providersToTry, coremodels.DrivlyProvider, coremodels.AutoIsoProvider, coremodels.VincarioProvider, coremodels.DATGroupProvider)
82+
providersToTry = append(providersToTry, coremodels.DrivlyProvider, coremodels.VincarioProvider, coremodels.Japan17VIN, coremodels.AutoIsoProvider, coremodels.DATGroupProvider)
8383
} else {
8484
// use the specified override
8585
providersToTry = append(providersToTry, provider)
@@ -89,7 +89,6 @@ func (c vinDecodingService) GetVIN(ctx context.Context, vin string, provider cor
8989

9090
for _, p := range providersToTry {
9191
// try all the options, but need to continue if get an error
92-
// todo: break if decode works, continue if need to try with next
9392
switch p {
9493
case coremodels.TeslaProvider:
9594
v := vinutil.VIN(vin)
@@ -107,33 +106,41 @@ func (c vinDecodingService) GetVIN(ctx context.Context, vin string, provider cor
107106
FuelType: "electric",
108107
MetaData: null.JSONFrom(bytes),
109108
}
109+
err := validateVinDecoding(result)
110+
if err != nil {
111+
errFinal = err
112+
continue
113+
}
110114
localLog.Info().Msgf("decoded with tesla: %+v", result)
111115
return result, nil
112116
case coremodels.DrivlyProvider:
117+
localLog.Info().Msgf("trying to decode VIN: %s with drivly", vin)
113118
vinDrivlyInfo, err := c.drivlyAPISvc.GetVINInfo(vin)
114119
if err != nil {
115120
errFinal = errors.Wrapf(err, "unable to decode vin: %s with drivly", vin)
116121
continue
117122
}
118-
result, err = buildFromDrivly(vinDrivlyInfo)
123+
result, err = buildFromDrivly(vinDrivlyInfo) // already does validation
119124
if err != nil {
120125
errFinal = errors.Wrapf(err, "unable to decode vin: %s with drivly", vin)
121126
continue
122127
}
123128
return result, nil
124129
case coremodels.VincarioProvider:
130+
localLog.Info().Msgf("trying to decode VIN: %s with vincario", vin)
125131
vinVincarioInfo, err := c.vincarioAPISvc.DecodeVIN(vin)
126132
if err != nil {
127133
errFinal = errors.Wrapf(err, "unable to decode vin: %s with vincario", vin)
128134
continue
129135
}
130-
result, err = buildFromVincario(vinVincarioInfo)
136+
result, err = buildFromVincario(vinVincarioInfo) // already does validation
131137
if err != nil {
132138
errFinal = err
133139
continue
134140
}
135141
return result, nil
136142
case coremodels.Japan17VIN:
143+
localLog.Info().Msgf("trying to decode VIN: %s with 17vin", vin)
137144
mmy, raw, err := c.japan17VINAPI.GetVINInfo(vin)
138145
if err != nil {
139146
errFinal = errors.Wrapf(err, "unable to decode vin: %s with japan17vin", vin)
@@ -155,6 +162,7 @@ func (c vinDecodingService) GetVIN(ctx context.Context, vin string, provider cor
155162
}
156163
return result, nil
157164
case coremodels.CarVXVIN:
165+
localLog.Info().Msgf("trying to decode VIN: %s with carvx", vin)
158166
info, raw, err := c.carvxAPI.GetVINInfo(vin)
159167
if err != nil {
160168
errFinal = errors.Wrapf(err, "unable to decode vin: %s with carvx", vin)
@@ -180,87 +188,35 @@ func (c vinDecodingService) GetVIN(ctx context.Context, vin string, provider cor
180188
}
181189
return result, nil
182190
case coremodels.AutoIsoProvider:
191+
localLog.Info().Msgf("trying to decode VIN: %s with autoiso", vin)
183192
vinAutoIsoInfo, err := c.autoIsoAPIService.GetVIN(vin)
184193
if err != nil {
185194
errFinal = errors.Wrapf(err, "unable to decode vin: %s with autoiso", vin)
186195
continue
187196
}
188-
result, err = buildFromAutoIso(vinAutoIsoInfo)
197+
result, err = buildFromAutoIso(vinAutoIsoInfo) // already does validation
189198
if err != nil {
190199
errFinal = err
191200
continue
192201
}
193202
return result, nil
194203
case coremodels.DATGroupProvider:
204+
localLog.Info().Msgf("trying to decode VIN: %s with datgroup", vin)
195205
// todo lookup country for two letter equiv
196206
vinInfo, err := c.DATGroupAPIService.GetVINv2(vin, country) // try with Turkey
197207
if err != nil {
198208
errFinal = errors.Wrapf(err, "unable to decode vin: %s with DATGroup", vin)
199209
continue
200210
}
201-
result, err = buildFromDATGroup(vinInfo)
211+
result, err = buildFromDATGroup(vinInfo) // already does validation
202212
if err != nil {
203213
errFinal = err
204214
continue
205215
}
206216
return result, nil
207217
case coremodels.AllProviders:
208-
//vinDrivlyInfo, err := c.drivlyAPISvc.GetVINInfo(vin)
209-
//if err != nil {
210-
// localLog.Warn().Err(err).Msg("AllProviders decode - unable decode vin with drivly")
211-
//} else {
212-
// result, err = buildFromDrivly(vinDrivlyInfo)
213-
// if err != nil {
214-
// localLog.Warn().Err(err).Msg("AllProviders decode -could not decode vin with drivly")
215-
// } else {
216-
// metadata, err := common.BuildDeviceTypeAttributes(buildDrivlyVINInfoToUpdateAttr(vinDrivlyInfo), dt)
217-
// if err != nil {
218-
// localLog.Warn().Err(err).Msg("AllProviders decode - unable to build metadata attributes")
219-
// }
220-
// result.MetaData = metadata
221-
// }
222-
//}
223-
//
224-
//// if nothing from drivly, try autoiso
225-
//if result == nil || result.Source == "" {
226-
// autoIsoInfo, err := c.autoIsoAPIService.GetVIN(vin)
227-
// if err != nil {
228-
// localLog.Warn().Err(err).Msg("AllProviders decode -could not decode vin with autoiso")
229-
// } else {
230-
// result, err = buildFromAutoIso(autoIsoInfo)
231-
// if err != nil {
232-
// localLog.Warn().Err(err).Msg("AllProviders decode -could not build struct from autoiso data")
233-
// }
234-
// }
235-
//}
236-
//
237-
//// if nothing,try vincario
238-
//if result == nil || result.Source == "" {
239-
// vinVincarioInfo, err := c.vincarioAPISvc.DecodeVIN(vin)
240-
// if err != nil {
241-
// localLog.Warn().Err(err).Msg("AllProviders decode -could not decode vin with vincario")
242-
// } else {
243-
// result, err = buildFromVincario(vinVincarioInfo)
244-
// if err != nil {
245-
// localLog.Warn().Err(err).Msg("AllProviders decode -could not build struct from vincario data")
246-
// }
247-
// }
248-
//}
249-
//
250-
//// if nothing from vincario, try DATGroup
251-
//if result == nil || result.Source == "" {
252-
// // idea: only accept WMI's for DATgroup that they have succesfully decoded in the past
253-
// datGroupInfo, err := c.DATGroupAPIService.GetVINv2(vin, country)
254-
// if err != nil {
255-
// localLog.Warn().Err(err).Msg("AllProviders decode -could not decode vin with DATGroup")
256-
// } else {
257-
// result, err = buildFromDATGroup(datGroupInfo)
258-
// localLog.Info().Msgf("datgroup result: %+v", result) // temporary for debugging
259-
// if err != nil {
260-
// localLog.Warn().Err(err).Msg("AllProviders decode - could not build struct from DATGroup data")
261-
// }
262-
// }
263-
//}
218+
// this should never hit
219+
errFinal = fmt.Errorf("all providers - invalid option reached")
264220
}
265221
}
266222

0 commit comments

Comments
 (0)