From f42bebc486efb8d9bea846857f52cac1cd264939 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A1=D0=B8=D0=BD=D0=BA=D0=B5=D0=B2=D0=B8=D1=87=20=D0=9C?= =?UTF-8?q?=D0=B8=D1=85=D0=B0=D0=B8=D0=BB=20=D0=9C=D0=B8=D1=85=D0=B0=D0=B9?= =?UTF-8?q?=D0=BB=D0=BE=D0=B2=D0=B8=D1=87?= Date: Mon, 19 Apr 2021 13:51:30 +0700 Subject: [PATCH] Additional SubRecordType: EGTS_SR_ACCEL_DATA --- egts/packet/codes.go | 4 +- egts/packet/record_data.go | 8 +- egts/packet_test/record_data_test.go | 2 +- egts/subrecord/sr_acceleration_data.go | 170 ++++++++++++++++++ .../sr_acceleration_data_test.go | 64 +++++++ 5 files changed, 239 insertions(+), 9 deletions(-) create mode 100644 egts/subrecord/sr_acceleration_data.go create mode 100644 egts/subrecord_test/sr_acceleration_data_test.go diff --git a/egts/packet/codes.go b/egts/packet/codes.go index 23fa05c..1dd7827 100644 --- a/egts/packet/codes.go +++ b/egts/packet/codes.go @@ -17,8 +17,8 @@ var ( ExtPosData = uint8(17) // EGTS_SR_EXT_POS_DATA AdSensorsData = uint8(18) // EGTS_SR_AD_SENSORS_DATA CountersData = uint8(19) // EGTS_SR_COUNTERS_DATA - StateDataType = uint8(20) // Type for EGTS_SR_STATE_DATA - StateData = uint8(21) // EGTS_SR_STATE_DATA + StateData = uint8(20) // EGTS_SR_STATE_DATA + AccelerationData = uint8(21) // EGTS_SR_ACCEL_DATA LiquidLevelSensor = uint8(27) // EGTS_SR_LIQUID_LEVEL_SENSOR ) diff --git a/egts/packet/record_data.go b/egts/packet/record_data.go index 72a2e5b..88db0dd 100644 --- a/egts/packet/record_data.go +++ b/egts/packet/record_data.go @@ -57,12 +57,8 @@ func (rd *RecordsData) Decode(b []byte) (err error) { case CountersData: rdEntity.SubrecordData = &subrecord.SRCountersData{} break - case StateDataType: - if rdEntity.SubrecordLength == 5 { - rdEntity.SubrecordData = &subrecord.SRStateData{} - } else { - // @todo - } + case AccelerationData: + rdEntity.SubrecordData = &subrecord.SRAccelerationHeader{} break case StateData: rdEntity.SubrecordData = &subrecord.SRStateData{} diff --git a/egts/packet_test/record_data_test.go b/egts/packet_test/record_data_test.go index a7a3d8f..2d86174 100644 --- a/egts/packet_test/record_data_test.go +++ b/egts/packet_test/record_data_test.go @@ -8,7 +8,7 @@ import ( ) var ( - RecordsDataCheckIncome = []string{"1018009edd050f5fb4b49e8d7da2359b00009bc8550f030012010011040018110000120c000000070000000000000000001307000300000000000014050002860014041b0700400000fbff00001b0700000100000000001b0700010100000000001b07000201006c6300001b0700030100000000001b0700040100000000001b0700050100000000001b0700000200000000001b070001020000000000"} + RecordsDataCheckIncome = []string{"1018009edd050f5fb4b49e8d7da2359b00009bc8550f030012010011040018110000120c000000070000000000000000001307000300000000000014050002860014041b0700400000fbff00001b0700000100000000001b0700010100000000001b07000201006c6300001b0700030100000000001b0700040100000000001b0700050100000000001b0700000200000000001b07000102000000000015150002d854311539300a1a611eb82239300a1a611eb822"} ) func TestRecordsDataDecoding(t *testing.T) { diff --git a/egts/subrecord/sr_acceleration_data.go b/egts/subrecord/sr_acceleration_data.go new file mode 100644 index 0000000..fa96979 --- /dev/null +++ b/egts/subrecord/sr_acceleration_data.go @@ -0,0 +1,170 @@ +package subrecord + +import ( + "bytes" + "encoding/binary" + "fmt" + "time" +) + +// SRAcceleration EGTS_SR_ACCEL_DATA +/* + Применяется АСН для передачи на аппаратно- + программный комплекс данных о + состоянии +*/ + +type SRAccelerationData struct { + RTM uint16 `json:"RTM"` // RTM (Relative Time) + XAAV int16 `json:"XAAV"` // XAAV (X Axis Acceleration Value) + YAAV int16 `json:"YAAV"` // YAAV (Y Axis Acceleration Value) + ZAAV int16 `json:"ZAAV"` // ZAAV (Z Axis Acceleration Value) +} + +// RecordsData Slice of RecordData +type SRAccelerationsData []*SRAccelerationData + +type SRAccelerationHeader struct { + StructuresAmount uint8 `json:"SA"` // SA - число передаваемых структур данных + AbsoluteTimeUint uint32 `json:"ATM"` // ATM - время проведения измерений первой передаваемой структуры + AbsoluteTime time.Time `json:"ATM_RFC3339"` // ATM - время + AccelerationData SRAccelerationsData `json:"ADS"` // ADS - структуры данных показаний акселерометра +} + +// Decode Parse array of bytes to EGTS_SR_ACCEL_DATA +func (subr *SRAccelerationData) Decode(b []byte) (err error) { + buffer := bytes.NewReader(b) + + rtm := make([]byte, 2) + if _, err = buffer.Read(rtm); err != nil { + return fmt.Errorf("EGTS_SR_ACCEL_DATA; Error reading RTM") + } + + subr.RTM = binary.LittleEndian.Uint16(rtm) + + x := make([]byte, 2) + if _, err = buffer.Read(x); err != nil { + return fmt.Errorf("EGTS_SR_ACCEL_DATA; Error reading XAAV") + } + + subr.XAAV = int16(binary.LittleEndian.Uint16(x)) + + y := make([]byte, 2) + if _, err = buffer.Read(y); err != nil { + return fmt.Errorf("EGTS_SR_ACCEL_DATA; Error reading YAAV") + } + + subr.YAAV = int16(binary.LittleEndian.Uint16(y)) + + z := make([]byte, 2) + if _, err = buffer.Read(z); err != nil { + return fmt.Errorf("EGTS_SR_ACCEL_DATA; Error reading ZAAV") + } + + subr.ZAAV = int16(binary.LittleEndian.Uint16(z)) + + return nil +} + +// Encode Parse EGTS_SR_ACCEL_DATA to array of bytes +func (subr *SRAccelerationData) Encode() (b []byte, err error) { + buffer := new(bytes.Buffer) + + if err = binary.Write(buffer, binary.LittleEndian, subr.RTM); err != nil { + return nil, fmt.Errorf("EGTS_SR_ACCEL_DATA; Error writing RTM") + } + + if err = binary.Write(buffer, binary.LittleEndian, subr.XAAV); err != nil { + return nil, fmt.Errorf("EGTS_SR_ACCEL_DATA; Error writing XAAV") + } + + if err = binary.Write(buffer, binary.LittleEndian, subr.YAAV); err != nil { + return nil, fmt.Errorf("EGTS_SR_ACCEL_DATA; Error writing YAAV") + } + + if err = binary.Write(buffer, binary.LittleEndian, subr.ZAAV); err != nil { + return nil, fmt.Errorf("EGTS_SR_ACCEL_DATA; Error writing ZAAV") + } + + return buffer.Bytes(), nil +} + +// Len Returns length of bytes slice +func (subr *SRAccelerationData) Len() (l uint16) { + encoded, _ := subr.Encode() + l = uint16(len(encoded)) + + return l +} + +// Decode Parse array of bytes to EGTS_SR_ACCEL_DATA +func (subr *SRAccelerationHeader) Decode(b []byte) (err error) { + buffer := bytes.NewReader(b) + + if subr.StructuresAmount, err = buffer.ReadByte(); err != nil { + return fmt.Errorf("EGTS_SR_ACCEL_DATA; Error reading SA") + } + + timestamp, _ := time.Parse(time.RFC3339, "2010-01-01T00:00:00+00:00") + nt := make([]byte, 4) + + if _, err = buffer.Read(nt); err != nil { + return fmt.Errorf("EGTS_SR_ACCEL_DATA; Error reading NTM") + } + + subr.AbsoluteTimeUint = binary.LittleEndian.Uint32(nt) + subr.AbsoluteTime = timestamp.Add(time.Duration(int(subr.AbsoluteTimeUint)) * time.Second) + + subr.AccelerationData = SRAccelerationsData{} + + ads := &SRAccelerationData{} + + for buffer.Len() > 0 { + bb := make([]byte, 8) + if _, err = buffer.Read(bb); err != nil { + return err + } + + err := ads.Decode(bb) + if err != nil { + return fmt.Errorf("EGTS_SR_ACCEL_DATA;" + err.Error()) + } + + subr.AccelerationData = append(subr.AccelerationData, ads) + } + + return nil +} + +// Encode Parse EGTS_SR_ACCEL_DATA to array of bytes +func (subr *SRAccelerationHeader) Encode() (b []byte, err error) { + buffer := new(bytes.Buffer) + + if err = buffer.WriteByte(subr.StructuresAmount); err != nil { + return nil, fmt.Errorf("EGTS_SR_ACCEL_DATA; Error writing SA") + } + + timestamp, _ := time.Parse(time.RFC3339, "2010-01-01T00:00:00+00:00") + if err = binary.Write(buffer, binary.LittleEndian, uint32(subr.AbsoluteTime.Sub(timestamp).Seconds())); err != nil { + return nil, fmt.Errorf("EGTS_SR_ACCEL_DATA; Error writing NTM") + } + + for _, sr := range subr.AccelerationData { + rd, err := sr.Encode() + if err != nil { + return nil, fmt.Errorf("EGTS_SR_ACCEL_DATA;" + err.Error()) + } + + buffer.Write(rd) + } + + return buffer.Bytes(), nil +} + +// Len Returns length of bytes slice +func (subr *SRAccelerationHeader) Len() (l uint16) { + encoded, _ := subr.Encode() + l = uint16(len(encoded)) + + return l +} diff --git a/egts/subrecord_test/sr_acceleration_data_test.go b/egts/subrecord_test/sr_acceleration_data_test.go new file mode 100644 index 0000000..7da8f62 --- /dev/null +++ b/egts/subrecord_test/sr_acceleration_data_test.go @@ -0,0 +1,64 @@ +package subrecord + +import ( + "encoding/hex" + "testing" + + "github.com/LdDl/go-egts/egts/subrecord" +) + +var ( + SRAccelerationDataCheckIncome = []string{"39300a1a611eb822"} +) + +func TestSRAccelerationDataDecoding(t *testing.T) { + for i := range SRAccelerationDataCheckIncome { + pkgHex := SRAccelerationDataCheckIncome[i] + pkgBytes, err := hex.DecodeString(pkgHex) + if err != nil { + t.Errorf("Error: %s", err.Error()) + } + subr := subrecord.SRAccelerationData{} + err = subr.Decode(pkgBytes) + if err != nil { + t.Errorf("Error: %s", err.Error()) + } + + hexed, err := subr.Encode() + if err != nil { + t.Errorf("Error: %s", err.Error()) + } + if hex.EncodeToString(hexed) != SRAccelerationDataCheckIncome[i] { + t.Errorf("Have to be %s, but got %s", SRAccelerationDataCheckIncome[i], hex.EncodeToString(hexed)) + } + } +} + +var ( + SRAccelerationHeaderCheckIncome = []string{ + "02d854311539300a1a611eb82239300a1a611eb822", + } +) + +func TestSRAccelerationHeaderDecoding(t *testing.T) { + for i := range SRAccelerationHeaderCheckIncome { + pkgHex := SRAccelerationHeaderCheckIncome[i] + pkgBytes, err := hex.DecodeString(pkgHex) + if err != nil { + t.Errorf("Error: %s", err.Error()) + } + subr := subrecord.SRAccelerationHeader{} + err = subr.Decode(pkgBytes) + if err != nil { + t.Errorf("Error: %s", err.Error()) + } + + hexed, err := subr.Encode() + if err != nil { + t.Errorf("Error: %s", err.Error()) + } + if hex.EncodeToString(hexed) != SRAccelerationHeaderCheckIncome[i] { + t.Errorf("Have to be %s, but got %s", SRAccelerationHeaderCheckIncome[i], hex.EncodeToString(hexed)) + } + } +}