update current project state

This commit is contained in:
gqc
2026-07-03 20:55:15 +08:00
parent 6056b1fdc5
commit 13c4d03055
13 changed files with 1084 additions and 185 deletions
+175 -30
View File
@@ -6,6 +6,7 @@ import (
"fmt"
"os"
"path/filepath"
"strconv"
"strings"
)
@@ -25,15 +26,15 @@ type Point struct {
// ServiceConfig 服务配置结构体
type ServiceConfig struct {
HostUUID string `json:"host_uuid"`
DeviceUUID string `json:"device_uuid"`
Address string `json:"address"`
TaskID string `json:"task_id"`
CameraRTSP string `json:"camera_rtsp"`
CameraIP string `json:"camera_ip"`
Confidence int `json:"confidence"`
HostUUID string `json:"host_uuid"`
DeviceUUID string `json:"device_uuid"`
Address string `json:"address"`
TaskID string `json:"task_id"`
CameraRTSP string `json:"camera_rtsp"`
CameraIP string `json:"camera_ip"`
Confidence int `json:"confidence"`
DetectArea DetectAreaConfig `json:"detect_area"`
Param ParamConfig `json:"param"`
Param ParamConfig `json:"param"`
}
// DetectAreaConfig 检测区域配置
@@ -56,19 +57,21 @@ type FireCheckParam struct {
// FireLeaveParam 离岗参数
type FireLeaveParam struct {
PersonCount string `json:"person_count"`
Confidence string `json:"confidence"`
DetectionTime string `json:"detection_time"`
PersonCount string `json:"person_count"`
Confidence string `json:"confidence"`
DetectionTime string `json:"detection_time"`
TemperatureThreshold string `json:"temperature_threshold"`
AlarmTime string `json:"alarm_time"`
AlarmTime string `json:"alarm_time"`
}
var (
devicesBaseDir = "/data/devices"
deviceDataList []DeviceData
devicesBaseDir = "/data/devices"
deviceDataList []DeviceData
serviceConfigFile = "/usr/local/etc/service.conf"
)
const fixedUploadURL = "http://172.17.0.1/api/v1/upload/video"
// LoadServiceConfig loads multiple device data from service config file
func LoadServiceConfig() ([]DeviceData, error) {
if _, err := os.Stat(serviceConfigFile); os.IsNotExist(err) {
@@ -88,35 +91,43 @@ func LoadServiceConfig() ([]DeviceData, error) {
return nil, fmt.Errorf("service config file is empty")
}
// Parse as ServiceConfig array
// Parse as the canonical ServiceConfig array. Fall back to the previous
// DeviceData array cache shape so older local service.conf files still boot.
var serviceConfigs []ServiceConfig
if err := json.Unmarshal(data, &serviceConfigs); err != nil {
logger.Logger.Printf("Failed to parse service config file: %v", err)
return nil, err
var legacyDeviceData []DeviceData
if legacyErr := json.Unmarshal(data, &legacyDeviceData); legacyErr != nil {
logger.Logger.Printf("Failed to parse service config file: %v", err)
return nil, err
}
for i := range legacyDeviceData {
NormalizeDeviceRuntimeFields(&legacyDeviceData[i])
}
logger.Logger.Printf("Loaded %d legacy device configurations from service config file", len(legacyDeviceData))
return legacyDeviceData, nil
}
// Convert ServiceConfig to DeviceData
var deviceDataList []DeviceData
const FixedUploadURL = "http://192.168.80.168/api/v1/upload/video"
for _, config := range serviceConfigs {
// Create DeviceData from ServiceConfig
deviceData := DeviceData{
DeviceUUID: config.DeviceUUID,
TaskID: config.TaskID,
CameraRTSP: config.CameraRTSP,
CameraIP: config.CameraIP,
Confidence: config.Confidence,
HostUUID: config.HostUUID,
Address: config.Address,
UploadURL: FixedUploadURL,
DeviceUUID: config.DeviceUUID,
TaskID: config.TaskID,
CameraRTSP: config.CameraRTSP,
CameraIP: config.CameraIP,
Confidence: config.Confidence,
HostUUID: config.HostUUID,
Address: config.Address,
UploadURL: fixedUploadURL,
// Set new fields for new configuration format
FireLeaveDetectArea: config.DetectArea.FireLeave,
FireCheckDetectArea: config.DetectArea.FireCheck,
FireLeaveParam: config.Param.FireLeave,
FireCheckParam: config.Param.FireCheck,
}
// Parse and set temperature threshold from FireLeaveParam
if tempThresholdStr := config.Param.FireLeave.TemperatureThreshold; tempThresholdStr != "" {
var tempThreshold float64
@@ -125,6 +136,7 @@ func LoadServiceConfig() ([]DeviceData, error) {
logger.Logger.Printf("Set temperature threshold from config: %.1f°C (DeviceUUID=%s)", tempThreshold, config.DeviceUUID)
}
}
NormalizeDeviceRuntimeFields(&deviceData)
// Filter out configurations with empty DeviceUUID
if deviceData.DeviceUUID != "" {
@@ -141,6 +153,123 @@ func LoadServiceConfig() ([]DeviceData, error) {
return deviceDataList, nil
}
func DecodeDeviceDataPayload(data []byte) (DeviceData, error) {
var deviceData DeviceData
if err := json.Unmarshal(data, &deviceData); err == nil && deviceData.DeviceUUID != "" {
NormalizeDeviceRuntimeFields(&deviceData)
if deviceData.UploadURL == "" {
deviceData.UploadURL = fixedUploadURL
}
return deviceData, nil
}
var serviceConfig ServiceConfig
if err := json.Unmarshal(data, &serviceConfig); err != nil {
return DeviceData{}, err
}
deviceData = ServiceConfigToDeviceData(serviceConfig, fixedUploadURL)
if deviceData.DeviceUUID == "" {
return DeviceData{}, fmt.Errorf("device_uuid is empty")
}
return deviceData, nil
}
func ServiceConfigToDeviceData(config ServiceConfig, uploadURL string) DeviceData {
deviceData := DeviceData{
DeviceUUID: config.DeviceUUID,
TaskID: config.TaskID,
CameraRTSP: config.CameraRTSP,
CameraIP: config.CameraIP,
Confidence: config.Confidence,
HostUUID: config.HostUUID,
Address: config.Address,
UploadURL: uploadURL,
FireLeaveDetectArea: config.DetectArea.FireLeave,
FireCheckDetectArea: config.DetectArea.FireCheck,
FireLeaveParam: config.Param.FireLeave,
FireCheckParam: config.Param.FireCheck,
}
NormalizeDeviceRuntimeFields(&deviceData)
return deviceData
}
func DeviceDataToServiceConfig(deviceData DeviceData) ServiceConfig {
config := ServiceConfig{
HostUUID: deviceData.HostUUID,
DeviceUUID: deviceData.DeviceUUID,
Address: deviceData.Address,
TaskID: deviceData.TaskID,
CameraRTSP: deviceData.CameraRTSP,
CameraIP: deviceData.CameraIP,
Confidence: deviceData.Confidence,
DetectArea: DetectAreaConfig{
FireLeave: deviceData.FireLeaveDetectArea,
FireCheck: deviceData.FireCheckDetectArea,
},
Param: ParamConfig{
FireLeave: deviceData.FireLeaveParam,
FireCheck: deviceData.FireCheckParam,
},
}
if len(config.DetectArea.FireLeave) == 0 {
config.DetectArea.FireLeave = deviceData.DetectArea
}
if config.Param.FireLeave.DetectionTime == "" && deviceData.DetectionTime != "" {
config.Param.FireLeave.DetectionTime = deviceData.DetectionTime.String()
}
if config.Param.FireLeave.AlarmTime == "" && deviceData.AlarmTime != "" {
config.Param.FireLeave.AlarmTime = deviceData.AlarmTime.String()
}
if config.Param.FireLeave.TemperatureThreshold == "" && deviceData.TemperatureThreshold > 0 {
config.Param.FireLeave.TemperatureThreshold = strconv.FormatFloat(deviceData.TemperatureThreshold, 'f', -1, 64)
}
if config.Param.FireLeave.Confidence == "" && deviceData.Confidence > 0 {
config.Param.FireLeave.Confidence = strconv.Itoa(deviceData.Confidence)
}
if config.Param.FireCheck.Confidence == "" && deviceData.Confidence > 0 {
config.Param.FireCheck.Confidence = strconv.Itoa(deviceData.Confidence)
}
return config
}
func NormalizeDeviceRuntimeFields(deviceData *DeviceData) {
if deviceData == nil {
return
}
if len(deviceData.FireLeaveDetectArea) == 0 && len(deviceData.DetectArea) > 0 {
deviceData.FireLeaveDetectArea = deviceData.DetectArea
}
if len(deviceData.DetectArea) == 0 && len(deviceData.FireLeaveDetectArea) > 0 {
deviceData.DetectArea = deviceData.FireLeaveDetectArea
}
if deviceData.FireLeaveParam.PersonCount != "" {
if count, err := strconv.Atoi(deviceData.FireLeaveParam.PersonCount); err == nil && count >= 0 {
deviceData.PersonCount = count
}
}
if deviceData.FireLeaveParam.DetectionTime != "" {
deviceData.DetectionTime = json.Number(deviceData.FireLeaveParam.DetectionTime)
}
if deviceData.FireLeaveParam.AlarmTime != "" {
deviceData.AlarmTime = json.Number(deviceData.FireLeaveParam.AlarmTime)
}
if deviceData.FireLeaveParam.TemperatureThreshold != "" {
if threshold, err := strconv.ParseFloat(deviceData.FireLeaveParam.TemperatureThreshold, 64); err == nil && threshold > 0 {
deviceData.TemperatureThreshold = threshold
logger.Logger.Printf("Set temperature threshold from config: %.1f掳C (DeviceUUID=%s)", threshold, deviceData.DeviceUUID)
}
}
if deviceData.FireLeaveParam.Confidence != "" {
if confidence, err := strconv.Atoi(deviceData.FireLeaveParam.Confidence); err == nil && confidence > 0 {
deviceData.Confidence = confidence
}
}
}
// ProcessDetectAreaForInference processes detection area data, converts to format required by inference program
func ProcessDetectAreaForInference(areas []Area) string {
if len(areas) == 0 {
@@ -165,20 +294,22 @@ func ProcessDetectAreaForInference(areas []Area) string {
func ProcessDeviceDataForInference(data DeviceData) DeviceData {
// Create a copy, only process fields that need conversion
processed := data
NormalizeDeviceRuntimeFields(&processed)
// For backward compatibility, process original DetectArea if FireLeaveDetectArea is empty
if len(data.FireLeaveDetectArea) > 0 {
processed.DetectAreaStr = ProcessDetectAreaForInference(data.FireLeaveDetectArea)
} else {
processed.DetectAreaStr = ProcessDetectAreaForInference(data.DetectArea)
}
return processed
}
// ProcessFireLeaveDataForInference processes device data for fire_leave inference
func ProcessFireLeaveDataForInference(data DeviceData) DeviceData {
processed := data
NormalizeDeviceRuntimeFields(&processed)
if len(data.FireLeaveDetectArea) > 0 {
processed.DetectAreaStr = ProcessDetectAreaForInference(data.FireLeaveDetectArea)
}
@@ -188,6 +319,7 @@ func ProcessFireLeaveDataForInference(data DeviceData) DeviceData {
// ProcessFireCheckDataForInference processes device data for fire_check inference
func ProcessFireCheckDataForInference(data DeviceData) DeviceData {
processed := data
NormalizeDeviceRuntimeFields(&processed)
if len(data.FireCheckDetectArea) > 0 {
processed.DetectAreaStr = ProcessDetectAreaForInference(data.FireCheckDetectArea)
}
@@ -380,12 +512,25 @@ func UpdateDeviceData(data DeviceData) error {
// SaveServiceConfig saves multiple device configurations to service config file
func SaveServiceConfig(deviceDataList []DeviceData) error {
configData, err := json.MarshalIndent(deviceDataList, "", " ")
serviceConfigs := make([]ServiceConfig, 0, len(deviceDataList))
for _, deviceData := range deviceDataList {
if deviceData.DeviceUUID == "" {
continue
}
serviceConfigs = append(serviceConfigs, DeviceDataToServiceConfig(deviceData))
}
configData, err := json.MarshalIndent(serviceConfigs, "", " ")
if err != nil {
logger.Logger.Printf("Failed to serialize service configuration: %v", err)
return err
}
if err := os.MkdirAll(filepath.Dir(serviceConfigFile), 0755); err != nil {
logger.Logger.Printf("Failed to create service config directory: %v", err)
return err
}
if err := os.WriteFile(serviceConfigFile, configData, 0644); err != nil {
logger.Logger.Printf("Failed to write service config file: %v", err)
return err