package connect import ( "FireLeave_tool/logger" "encoding/json" "fmt" "os" "path/filepath" "strings" ) // Modified device data storage path var ( devicesBaseDir = "/data/devices" deviceDataList []DeviceData ) // InitializeDevicesFromServiceConfig Initialize device data from service configuration func InitializeDevicesFromServiceConfig() ([]DeviceData, error) { deviceDataMutex.Lock() defer deviceDataMutex.Unlock() logger.Logger.Printf("Initializing device data from service configuration...") // Ensure device directory exists if err := os.MkdirAll(devicesBaseDir, 0755); err != nil { logger.Logger.Printf("Failed to create device directory: %v", err) return nil, err } logger.Logger.Printf("Device directory confirmed: %s", devicesBaseDir) // Load from service configuration configs, err := LoadServiceConfig() if err != nil { logger.Logger.Printf("Failed to load from service configuration: %v", err) return nil, err } logger.Logger.Printf("Loaded %d devices from service configuration", len(configs)) // Clear existing device data deviceDataList = []DeviceData{} // Process each device and save to individual files for i, config := range configs { processedData := ProcessDeviceDataForInference(config) deviceDataList = append(deviceDataList, processedData) // Save to individual device file if err := saveDeviceToFile(processedData); err != nil { logger.Logger.Printf("Failed to save the device file [%s]: %v", processedData.DeviceUUID, err) continue } logger.Logger.Printf("Processed device [%d]: UUID=%s", i, processedData.DeviceUUID) } logger.Logger.Printf("Device data initialization completed, %d devices", len(deviceDataList)) return deviceDataList, nil } // saveDeviceToFile Save individual device data to separate file func saveDeviceToFile(deviceData DeviceData) error { filePath := filepath.Join(devicesBaseDir, fmt.Sprintf("device_%s.json", deviceData.DeviceUUID)) // Clean device data to ensure no invalid characters cleanedData := cleanDeviceData(deviceData) data, err := json.MarshalIndent(cleanedData, "", " ") if err != nil { logger.Logger.Printf("Device data serialization failed: %v, Device data: %+v", err, cleanedData) return fmt.Errorf("Device data serialization failed: %v", err) } // Write directly to file if err := os.WriteFile(filePath, data, 0644); err != nil { return fmt.Errorf("Failed to write device file: %v", err) } logger.Logger.Printf("Device data saved successfully: %s", filePath) return nil } // cleanDeviceData Clean device data, remove possible invalid characters func cleanDeviceData(data DeviceData) DeviceData { cleaned := data // Clean string fields cleaned.DeviceUUID = cleanString(data.DeviceUUID) cleaned.TaskID = cleanString(data.TaskID) cleaned.CameraRTSP = cleanString(data.CameraRTSP) cleaned.CameraIP = cleanString(data.CameraIP) cleaned.UploadURL = cleanString(data.UploadURL) cleaned.DetectAreaStr = cleanString(data.DetectAreaStr) // Ensure numeric fields are valid if cleaned.Confidence < 0 || cleaned.Confidence > 100 { cleaned.Confidence = 70 // Default value } if cleaned.CameraChannel < 0 { cleaned.CameraChannel = 0 } if cleaned.PersonCount < 0 { cleaned.PersonCount = 0 } if cleaned.Temperature < 0 { cleaned.Temperature = 0 } if cleaned.TemperatureThreshold <= 0 { cleaned.TemperatureThreshold = 45.0 // Default value } return cleaned } func cleanString(s string) string { // Remove control characters and invalid Unicode characters return strings.Map(func(r rune) rune { if r == 0xFFFD { // Unicode replacement character return -1 } if r < 32 && r != 9 && r != 10 && r != 13 { // Keep tab, newline, carriage return return -1 } return r }, s) } // GetDeviceDataList Get device data list func GetDeviceDataList() []DeviceData { deviceDataMutex.Lock() defer deviceDataMutex.Unlock() // If no data in memory, try to load from device files if len(deviceDataList) == 0 { logger.Logger.Printf("No device data in memory, loading from device files...") if err := loadDevicesFromFiles(); err != nil { logger.Logger.Printf("Failed to load from device files: %v", err) return []DeviceData{} } } // Return copy result := make([]DeviceData, len(deviceDataList)) copy(result, deviceDataList) return result } // loadDevicesFromFiles Load data from device files func loadDevicesFromFiles() error { // Clear existing data deviceDataList = []DeviceData{} // Read all files in device directory files, err := filepath.Glob(filepath.Join(devicesBaseDir, "device_*.json")) if err != nil { return fmt.Errorf("Failed to find device files: %v", err) } logger.Logger.Printf("Found %d device files", len(files)) for _, file := range files { data, err := os.ReadFile(file) if err != nil { logger.Logger.Printf("Failed to read device file %s: %v", file, err) continue } var deviceData DeviceData if err := json.Unmarshal(data, &deviceData); err != nil { logger.Logger.Printf("Failed to parse device file %s: %v", file, err) continue } deviceDataList = append(deviceDataList, deviceData) logger.Logger.Printf("Loaded device from file: UUID=%s", deviceData.DeviceUUID) } logger.Logger.Printf("Loaded %d devices from device files", len(deviceDataList)) return nil } // UpdateDeviceData Update device data func UpdateDeviceData(data DeviceData) error { deviceDataMutex.Lock() defer deviceDataMutex.Unlock() //logger.Logger.Printf("Updating device data [%s]", data.DeviceUUID) // Clean input data cleanedData := cleanDeviceData(data) // Find if device with same DeviceUUID already exists found := false for i, existing := range deviceDataList { if existing.DeviceUUID == cleanedData.DeviceUUID { deviceDataList[i] = cleanedData found = true //logger.Logger.Printf("Updated existing device: DeviceUUID=%s", cleanedData.DeviceUUID) break } } // If not exists, add to list if !found { logger.Logger.Printf("Adding new device to list: DeviceUUID=%s", cleanedData.DeviceUUID) deviceDataList = append(deviceDataList, cleanedData) } // Save to individual file if err := saveDeviceToFile(cleanedData); err != nil { logger.Logger.Printf("Failed to save device file: %v", err) return err } logger.Logger.Printf("Device data update completed: DeviceUUID=%s", cleanedData.DeviceUUID) return nil }