From d54ba33c59037b0ef9251f153754f3a753e859ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bla=C5=BE=20Dular?= <22869613+xBlaz3kx@users.noreply.github.com> Date: Fri, 13 Dec 2024 21:19:56 +0100 Subject: [PATCH] Bugfix: Payload (#4) * Fixed some fields from int to float, fixed timestamp validation * Added wrapped errors in builder, fixed message formatting * Fixed test --- builder.go | 11 ++++++----- builder_test.go | 2 +- payload.go | 28 ++++++++++++++-------------- validation.go | 2 +- 4 files changed, 22 insertions(+), 21 deletions(-) diff --git a/builder.go b/builder.go index 7e7982d..c193bcb 100644 --- a/builder.go +++ b/builder.go @@ -5,6 +5,7 @@ import ( "encoding/json" "fmt" + "github.com/pkg/errors" "github.com/samber/lo" ) @@ -122,24 +123,24 @@ func (b *Builder) Build() (*string, error) { // Validate payload err := b.payload.Validate() if err != nil { - return nil, err + return nil, errors.Wrap(err, "payload validation failed") } // Sign payload with private key err = b.signature.Sign(b.payload, b.privateKey) if err != nil { - return nil, err + return nil, errors.Wrap(err, "failed to sign message") } payload, err := json.Marshal(b.payload) if err != nil { - return nil, err + return nil, errors.Wrap(err, "failed to marshal payload") } signature, err := json.Marshal(b.signature) if err != nil { - return nil, err + return nil, errors.Wrap(err, "failed to marshal signature") } - return lo.ToPtr(fmt.Sprintf("OCMF|%v|%v", payload, signature)), nil + return lo.ToPtr(fmt.Sprintf("OCMF|%s|%s", payload, signature)), nil } diff --git a/builder_test.go b/builder_test.go index 7481496..feddebb 100644 --- a/builder_test.go +++ b/builder_test.go @@ -57,7 +57,7 @@ func (s *builderTestSuite) TestBuilder_Valid() { s.Equal(string(RfidNone), builder.payload.IdentificationType) s.Len(builder.payload.Readings, 1) s.Equal("2018-07-24T13:22:04,000+0200", builder.payload.Readings[0].Time) - s.Equal(123, builder.payload.Readings[0].ReadingValue) + s.Equal(float64(123), builder.payload.Readings[0].ReadingValue) s.Equal(string(UnitskWh), builder.payload.Readings[0].ReadingUnit) s.Equal(string(MeterOk), builder.payload.Readings[0].Status) diff --git a/payload.go b/payload.go index c597647..744bbdc 100644 --- a/payload.go +++ b/payload.go @@ -200,7 +200,7 @@ type PayloadSection struct { MeterSerial string `json:"MS" validate:"required"` MeterFirmware string `json:"MF,omitempty"` // User assignment - IdentificationStatus bool `json:"IS" validate:"required"` + IdentificationStatus bool `json:"IS"` IdentificationLevel string `json:"IL,omitempty" validate:"omitempty,userAssignmentState"` IdentificationFlags []string `json:"IF" validate:"omitempty,max=4"` IdentificationType string `json:"IT" validate:"required,rfidState"` @@ -221,22 +221,22 @@ func (p *PayloadSection) Validate() error { } type LossCompensation struct { - Naming string `json:"LN"` - Identification int `json:"LI"` - CableResistance int `json:"LR"` - CableResistanceUnit int `json:"LU"` + Naming string `json:"LN"` + Identification int `json:"LI"` + CableResistance float64 `json:"LR"` + CableResistanceUnit string `json:"LU"` } type Reading struct { - Time string `json:"TM" validate:"required,iso8601"` - Transaction string `json:"TX,omitempty" validate:"omitempty,oneof=B C X E L R A P S T"` - ReadingValue int `json:"RV" validate:"required"` - ReadingIdentifier string `json:"RI,omitempty"` - ReadingUnit string `json:"RU" validate:"required,unit"` - ReadingType string `json:"RT,omitempty" validate:"omitempty,currentType"` - CumulatedLoss int `json:"CL,omitempty"` - ErrorFlags string `json:"EF,omitempty" validate:"omitempty,oneof=E t"` - Status string `json:"ST" validate:"required,meterError"` + Time string `json:"TM" validate:"required,iso8601"` + Transaction string `json:"TX,omitempty" validate:"omitempty,oneof=B C X E L R A P S T"` + ReadingValue float64 `json:"RV" validate:"required"` + ReadingIdentifier string `json:"RI,omitempty"` + ReadingUnit string `json:"RU" validate:"required,unit"` + ReadingType string `json:"RT,omitempty" validate:"omitempty,currentType"` + CumulatedLoss float64 `json:"CL,omitempty"` + ErrorFlags string `json:"EF,omitempty" validate:"omitempty,oneof=E t"` + Status string `json:"ST" validate:"required,meterError"` } func (r *Reading) Validate() error { diff --git a/validation.go b/validation.go index bb9bd02..b2506a3 100644 --- a/validation.go +++ b/validation.go @@ -71,7 +71,7 @@ func currentTypeValidator(fl validator.FieldLevel) bool { return isValidCurrentType(CurrentType(fl.Field().String())) } -var iso8601WithMillisRegex = regexp.MustCompile(`^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2},\d{3}[+-]\d{4}$`) +var iso8601WithMillisRegex = regexp.MustCompile(`^(?:19|20)\d{2}-(?:0[1-9]|1[0-2])-(?:0[1-9]|[12]\d|3[01])T(?:[01]\d|2[0-3]):[0-5]\d:[0-5]\d(?:Z|-0[1-9]|-1\d|-2[0-3]|-00:?(?:0[1-9]|[1-5]\d)|\+[01]\d|\+2[0-3])(?:|:?[0-5]\d)$`) func iso8601WithMillisValidator(fl validator.FieldLevel) bool { return iso8601WithMillisRegex.MatchString(fl.Field().String())