Add SPI data handling and serialization support
Introduced `SpiParameters` and related structs to process SPI data. Added JSON marshaling/unmarshaling logic and a handler for the "SPI" command in the server. This enables parsing and transforming SPI data effectively for device communication.
This commit is contained in:
		@@ -112,6 +112,18 @@ func handleCameraCoveredAlarm(sPack *n9m.SmartPackage, pack n9m.Package, respons
 | 
				
			|||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func handleSPI(_ *n9m.SmartPackage, pack n9m.Package) (err error) {
 | 
				
			||||||
 | 
						var params n9m.SpiParameters
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if err = pack.GetParametersAs(¶ms); err != nil {
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						fmt.Printf("%+v\n", params)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func createSmartPackage(conn net.Conn) (pack *n9m.SmartPackage) {
 | 
					func createSmartPackage(conn net.Conn) (pack *n9m.SmartPackage) {
 | 
				
			||||||
	pack = n9m.NewSmartPackage(conn)
 | 
						pack = n9m.NewSmartPackage(conn)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -120,6 +132,7 @@ func createSmartPackage(conn net.Conn) (pack *n9m.SmartPackage) {
 | 
				
			|||||||
	pack.AddJSONHandler("CERTIFICATE", "CONNECT", handleCertificateConnect)
 | 
						pack.AddJSONHandler("CERTIFICATE", "CONNECT", handleCertificateConnect)
 | 
				
			||||||
	pack.AddJSONHandler("CERTIFICATE", "KEEPALIVE", handleKeepAlive)
 | 
						pack.AddJSONHandler("CERTIFICATE", "KEEPALIVE", handleKeepAlive)
 | 
				
			||||||
	pack.AddJSONHandler("CONFIGMODEL", "GET", handleGetConfig)
 | 
						pack.AddJSONHandler("CONFIGMODEL", "GET", handleGetConfig)
 | 
				
			||||||
 | 
						pack.AddJSONHandler("DEVEMM", "SPI", handleSPI)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pack.AddAlarmHandler(n9m.AlarmTypeMotionDetection, handleUselessAlarms)
 | 
						pack.AddAlarmHandler(n9m.AlarmTypeMotionDetection, handleUselessAlarms)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										176
									
								
								devemm.go
									
									
									
									
									
								
							
							
						
						
									
										176
									
								
								devemm.go
									
									
									
									
									
								
							@@ -1,5 +1,12 @@
 | 
				
			|||||||
package n9m
 | 
					package n9m
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"encoding/json"
 | 
				
			||||||
 | 
						"fmt"
 | 
				
			||||||
 | 
						"strconv"
 | 
				
			||||||
 | 
						"time"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// main server util
 | 
					// main server util
 | 
				
			||||||
@@ -36,3 +43,172 @@ func (e *Package) ResponseGeolocation(errorCode int, errorCause string, serial i
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 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"`
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user