FireLeave_tool/connect/device_storage.go
2025-11-18 17:30:28 +08:00

218 lines
6.2 KiB
Go

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
}