package n9m import ( "encoding/json" "fmt" "strconv" "time" ) /* // main server util func (e *Package) RequestGeolocation(serial int, Sid string) { e.Payload = map[string]any{ "MODULE": "DEVEMM", "OPERATION": "GETPOS", "PARAMETER": map[string]any{ "SERIAL": serial, }, "SESSION": Sid, } } func (e *Package) ResponseGeolocation(errorCode int, errorCause string, serial int, longitude float32, latitude float32, altitude float32, speed int, course int, time string) { e.Payload = map[string]any{ "MODULE": "DEVEMM", "OPERATION": "GETPOS", "RESPONSE": map[string]any{ "ERRORCODE": errorCode, "ERRORCAUSE": errorCause, "SERIAL": serial, "P": map[string]any{ "V": errorCode == 0, "J": fmt.Sprintf("%4.6v", longitude), "W": fmt.Sprintf("%4.6v", latitude), "H": fmt.Sprintf("%4.6v", altitude), "S": speed, // unit - 0.01 km/h "C": course, // direction (angle from north) "T": time, // yyyymmddhhmmss }, }, } } */ // 3.4.5.28 type SpiParameters struct { DriveFlag uint `json:"T"` DataMask uint `json:"M"` Position GPSData `json:"P"` DeviceStatus SpiDeviceStatus `json:"S"` } // 3.4.5.28.1 type SpiDeviceStatus struct { Status3G uint `json:"G3"` Status3GStrength uint `json:"G3S"` Status4G uint `json:"G4"` Status4GStrength uint `json:"G4S"` WIFIStatus uint `json:"W"` WIFIStrength uint `json:"WS"` Voltage float64 `json:"V"` DeviceTemperature float64 `json:"DT"` IndoorTemperature float64 `json:"TC"` Speed float64 `json:"S"` KeyIgnitionState uint `json:"SW"` RecordStatus []uint `json:"RE"` Time time.Time `json:"T"` StorageDeviceNumber uint `json:"STC"` StorageDeviceInfo []StorageDeviceInfo `json:"SINFO"` VideoLossStatus []uint `json:"VS"` Humidity float64 `json:"H"` TotalMileage float64 `json:"TM"` HardDriveHeating uint `json:"HTR"` } func (g *SpiDeviceStatus) MarshalJSON() ([]byte, error) { var alias struct { Status3G uint `json:"G3"` Status3GStrength uint `json:"G3S"` Status4G uint `json:"G4"` Status4GStrength uint `json:"G4S"` WIFIStatus uint `json:"W"` WIFIStrength uint `json:"WS"` Voltage uint `json:"V"` DeviceTemperature uint `json:"DT"` IndoorTemperature uint `json:"TC"` Speed uint `json:"S"` SpeedUnits uint `json:"SU"` KeyIgnitionState uint `json:"SW"` RecordStatus []uint `json:"RE"` Time string `json:"T"` StorageDeviceNumber uint `json:"STC"` StorageDeviceInfo []StorageDeviceInfo `json:"SINFO"` VideoLossStatus []uint `json:"VS"` Humidity uint `json:"H"` TotalMileage string `json:"TM"` HardDriveHeating uint `json:"HTR"` } convert := func(v float64) uint { if v < 0 { return uint(-v * 100) } else { return uint((v + 100) * 100) } } alias.Status3G = g.Status3G alias.Status3GStrength = g.Status3GStrength alias.Status4G = g.Status4G alias.Status4GStrength = g.Status4GStrength alias.WIFIStatus = g.WIFIStatus alias.WIFIStrength = g.WIFIStrength alias.Voltage = uint(g.Voltage * 100) alias.DeviceTemperature = convert(g.DeviceTemperature) alias.IndoorTemperature = convert(g.IndoorTemperature) alias.Speed = uint(g.Speed * 100) alias.SpeedUnits = 0 alias.KeyIgnitionState = g.KeyIgnitionState alias.RecordStatus = g.RecordStatus alias.Time = g.Time.Format("20060102150405") alias.StorageDeviceNumber = g.StorageDeviceNumber alias.StorageDeviceInfo = g.StorageDeviceInfo alias.VideoLossStatus = g.VideoLossStatus alias.Humidity = uint(g.Humidity * 10000) alias.TotalMileage = fmt.Sprintf("%.6f", g.TotalMileage) alias.HardDriveHeating = g.HardDriveHeating return json.Marshal(alias) } func (g *SpiDeviceStatus) UnmarshalJSON(data []byte) (err error) { var alias struct { Status3G uint `json:"G3"` Status3GStrength uint `json:"G3S"` Status4G uint `json:"G4"` Status4GStrength uint `json:"G4S"` WIFIStatus uint `json:"W"` WIFIStrength uint `json:"WS"` Voltage uint `json:"V"` DeviceTemperature uint `json:"TD"` IndoorTemperature uint `json:"TC"` Speed uint `json:"S"` SpeedUnits uint `json:"SU"` KeyIgnitionState uint `json:"SW"` RecordStatus []uint `json:"RE"` Time string `json:"T"` StorageDeviceNumber uint `json:"STC"` StorageDeviceInfo []StorageDeviceInfo `json:"SINFO"` VideoLossStatus []uint `json:"VS"` Humidity uint `json:"H"` TotalMileage string `json:"TM"` HardDriveHeating uint `json:"HTR"` } if err = json.Unmarshal(data, &alias); err != nil { return } convert := func(v uint) float64 { if v < 10000 { return -float64(v) / 100 } else { return float64(v-10000) / 100 } } g.Status3G = alias.Status3G g.Status3GStrength = alias.Status3GStrength g.Status4G = alias.Status4G g.Status4GStrength = alias.Status4GStrength g.WIFIStatus = alias.WIFIStatus g.WIFIStrength = alias.WIFIStrength g.Voltage = float64(alias.Voltage) / 100 g.DeviceTemperature = convert(alias.DeviceTemperature) g.IndoorTemperature = convert(alias.IndoorTemperature) g.Speed = float64(alias.Speed) / 100.0 switch alias.SpeedUnits { case 0: break case 1: g.Speed *= 1.609 default: return fmt.Errorf("Strange speed units") } g.KeyIgnitionState = alias.KeyIgnitionState g.RecordStatus = alias.RecordStatus g.Time, _ = time.Parse("20060102150405", alias.Time) g.StorageDeviceNumber = alias.StorageDeviceNumber g.StorageDeviceInfo = alias.StorageDeviceInfo g.VideoLossStatus = alias.VideoLossStatus g.Humidity = float64(alias.Humidity) / 10000 if g.TotalMileage, err = strconv.ParseFloat(alias.TotalMileage, 64); err != nil { return fmt.Errorf("invalid longitude: %w", err) } g.HardDriveHeating = alias.HardDriveHeating return nil } // 3.4.5.28.3 type StorageDeviceInfo struct { Type uint `json:"T"` MediaTime uint `json:"O"` Status uint `json:"S"` Capacity uint `json:"TS"` FreeCapacity uint `json:"LS"` }