# Current Change Summary Date: 2026-05-13 ## 1. Configuration Ownership The startup device configuration is owned by: ```text /usr/local/etc/service.conf ``` This file is the Docker startup configuration source. The service reads it at startup and uses it to initialize devices, inference processes, detection areas, and runtime parameters. WebSocket messages must not update this file. ## 2. service.conf Schema `service.conf` is written as an array of `ServiceConfig` objects: ```json [ { "host_uuid": "", "device_uuid": "", "address": "", "task_id": "", "camera_rtsp": "", "camera_ip": "", "confidence": 70, "detect_area": { "fire_leave": [], "fire_check": [] }, "param": { "fire_check": { "confidence": "70", "detection_time": "2" }, "fire_leave": { "person_count": "0", "confidence": "70", "detection_time": "20", "temperature_threshold": "45", "alarm_time": "300" } } } ] ``` The service still tolerates the previous `DeviceData[]` cache shape when reading `service.conf`, but writes back only the canonical `ServiceConfig[]` shape. ## 3. service.conf Write Boundary The remaining write functions are: - `connect.SaveServiceConfig()` - `connect.SaveSingleServiceConfig()` They write to: ```text /usr/local/etc/service.conf ``` The old WebSocket path that wrote `publish.params.data` into `service.conf` is now disabled. If a WebSocket publish message contains `data`, the service logs and ignores it. ## 4. Runtime Device State Runtime state is stored under: ```text /data/devices/device_{device_uuid}.json ``` This includes operational values such as current temperature, current person count, and alarm cooldown state. This is separate from `service.conf`. ## 5. WebSocket Topic Responsibilities The service currently subscribes to: ```text /dhlr/alert /dhlr/forbid_time ``` ### /dhlr/alert This topic controls the local sound/light alarm. Handled by: ```text connect.HandleBuzzerAlert() ``` It reads: - `type` - `buzzer_duration` It triggers GPIO109. It does not write `service.conf`. ### /dhlr/forbid_time This topic controls the `fire_leave` reporting pause window. It reads: - `minute` It does not write `service.conf`. It writes the pause configuration to: ```text /data/cache/forbid_time_config.json ``` ## 6. forbid_time Persistence `forbid_time_config.json` now stores: ```json { "minute": "15", "start_time": 1770000000, "end_time": 1770000900 } ``` Meaning: - `minute`: configured pause duration - `start_time`: Unix timestamp when the current pause window started - `end_time`: Unix timestamp when the current pause window ends If Docker restarts while a pause window is still active, startup restores the pause window from `end_time`. If `end_time` is expired, no pause is restored. If `minute` is `0`, the pause window is cleared and `end_time` is written as `0`. ## 7. fire_leave Pause Behavior During an active pause window: - person detection continues - temperature reading continues - `fire_leave` reporting is skipped - `fire_check` reporting is not affected Default pause duration is: ```text 15 minutes ``` ## 8. Port Manager Fix Inference startup and heartbeat restart now use the same port manager: ```text connect.GlobalPortManager ``` This avoids restart failures caused by using a separate `portmanager.GlobalPortManager` state. ## 9. Known Remaining Risks 1. The protobuf WebSocket protocol migration is not implemented because this repository does not contain `service.proto` or generated Go protobuf types. 2. The `reporter` package still contains old event-cycle functions. GPIO no longer calls them, but the old reporter upload paths still reference event-cycle behavior. This should be cleaned after confirming no external dependency remains. 3. `fire_check` heartbeat restart currently calls a shared restart function that restarts both `fire_leave` and `fire_check`. This is functional but broader than necessary. 4. The local environment currently does not expose `go` or `gofmt`, so compilation and formatting have not been executed in this workspace.