Skip to content

Commit

Permalink
Users can set working hours and decide if they would like to store ou…
Browse files Browse the repository at this point in the history
…tput in redis server or not
  • Loading branch information
yihong1120 committed Dec 22, 2024
1 parent faaf5cd commit dea495d
Show file tree
Hide file tree
Showing 4 changed files with 89 additions and 23 deletions.
20 changes: 17 additions & 3 deletions README-zh-tw.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
<img src="https://img.shields.io/badge/pre--commit-4.0.1-blue?logo=pre-commit" alt="Pre-commit 4.0.1">
</a>
<a href="https://docs.pytest.org/en/latest/">
<img src="https://img.shields.io/badge/pytest-8.3.3-blue?logo=pytest" alt="pytest 8.3.3">
<img src="https://img.shields.io/badge/pytest-8.3.4-blue?logo=pytest" alt="pytest 8.3.4">
</a>
<a href="https://codecov.io/github/yihong1120/Construction-Hazard-Detection" >
<img src="https://codecov.io/github/yihong1120/Construction-Hazard-Detection/graph/badge.svg?token=E0M66BUS8D" alt="Codecov">
Expand Down Expand Up @@ -138,7 +138,10 @@
"detect_no_safety_vest_or_helmet": true,
"detect_near_machinery_or_vehicle": true,
"detect_in_restricted_area": true
}
},
"work_start_hour": 0,
"work_end_hour": 24,
"store_in_redis": true
},
{
"video_url": "streaming URL",
Expand All @@ -155,7 +158,10 @@
"detect_no_safety_vest_or_helmet": true,
"detect_near_machinery_or_vehicle": false,
"detect_in_restricted_area": true
}
},
"work_start_hour": 0,
"work_end_hour": 24,
"store_in_redis": true
}
]
```
Expand Down Expand Up @@ -198,6 +204,14 @@
- `detect_no_safety_vest_or_helmet`:偵測人員是否未配戴安全背心或頭盔。這對於在必須配備安全裝備以保護人員的場所監控其安全裝備要求的遵守情況至關重要。
- `detect_near_machinery_or_vehicle`:偵測人員是否危險地靠近機器或車輛。這有助於防止在建築工地或工業區經常遇到的因靠近重型設備或移動車輛而引起的事故。
- `detect_in_restricted_area`:偵測人員是否進入限製或控制區域。限制區域對於未經訓練的人員可能是危險的,或者可能包含敏感設備,因此此設定有助於控制對此類區域的存取。

- `work_start_hour`:指定係統應開始監控視訊串流的時間(24 小時格式)。這樣可以將監控限制在活躍的工作時間,從而減少定義的時間範圍之外的不必要的處理(例如,「7」表示上午 7:00)。

- `work_end_hour`:指定係統應停止監控視訊串流的時間(24 小時格式)。在此時間之後,監控將停止以最佳化資源使用(例如「18」表示下午 6:00)。

「work_start_hour」和「work_end_hour」一起定義一天中的監控時段。對於 24 小時監控,請將“work_start_hour”設為“0”,將“work_end_hour”設為“24”。

- `store_in_redis`:一個布林值,決定是否將處理後的幀和關聯的檢測資料儲存在 Redis 中。如果為“True”,系統會將資料儲存到 Redis 資料庫以供進一步使用,例如即時監控或與其他服務整合。如果為“False”,則 Redis 中不會保存任何資料。
<br>

<details>
Expand Down
20 changes: 17 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
<img src="https://img.shields.io/badge/pre--commit-4.0.1-blue?logo=pre-commit" alt="Pre-commit 4.0.1">
</a>
<a href="https://docs.pytest.org/en/latest/">
<img src="https://img.shields.io/badge/pytest-8.3.3-blue?logo=pytest" alt="pytest 8.3.3">
<img src="https://img.shields.io/badge/pytest-8.3.4-blue?logo=pytest" alt="pytest 8.3.4">
</a>
<a href="https://codecov.io/github/yihong1120/Construction-Hazard-Detection" >
<img src="https://codecov.io/github/yihong1120/Construction-Hazard-Detection/graph/badge.svg?token=E0M66BUS8D" alt="Codecov">
Expand Down Expand Up @@ -138,7 +138,10 @@ Before running the application, you need to configure the system by specifying t
"detect_no_safety_vest_or_helmet": true,
"detect_near_machinery_or_vehicle": true,
"detect_in_restricted_area": true
}
},
"work_start_hour": 7,
"work_end_hour": 18,
"store_in_redis": true
},
{
"video_url": "streaming URL",
Expand All @@ -155,7 +158,10 @@ Before running the application, you need to configure the system by specifying t
"detect_no_safety_vest_or_helmet": true,
"detect_near_machinery_or_vehicle": false,
"detect_in_restricted_area": true
}
},
"work_start_hour": 0,
"work_end_hour": 24,
"store_in_redis": true
}
]
```
Expand Down Expand Up @@ -199,6 +205,14 @@ Each object in the array represents a video stream configuration with the follow
- `detect_near_machinery_or_vehicle`: Detects if a person is dangerously close to machinery or vehicles. This helps prevent accidents caused by close proximity to heavy equipment or moving vehicles, often encountered in construction sites or industrial areas.
- `detect_in_restricted_area`: Detects if a person has entered a restricted or controlled area. Restricted areas may be dangerous for untrained personnel or may contain sensitive equipment, so this setting aids in controlling access to such zones.

- `work_start_hour`: Specifies the hour (in 24-hour format) when the system should start monitoring the video stream. This allows monitoring to be restricted to active work hours, reducing unnecessary processing outside the defined timeframe (e.g., `7` for 7:00 AM).

- `work_end_hour`: Specifies the hour (in 24-hour format) when the system should stop monitoring the video stream. Monitoring will cease after this time to optimise resource usage (e.g., `18` for 6:00 PM).

Together, `work_start_hour` and `work_end_hour` define the monitoring period during a day. For 24-hour monitoring, set `work_start_hour` to `0` and `work_end_hour` to `24`.

- `store_in_redis`: A boolean value that determines whether to store processed frames and associated detection data in Redis. If `True`, the system will save the data to a Redis database for further use, such as real-time monitoring or integration with other services. If `False`, no data will be saved in Redis.


<br>

Expand Down
29 changes: 26 additions & 3 deletions config/configuration.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,29 @@
"detect_no_safety_vest_or_helmet": true,
"detect_near_machinery_or_vehicle": true,
"detect_in_restricted_area": true
}
}
]
},
"work_start_hour": 7,
"work_end_hour": 18,
"store_in_redis": true
},
{
"video_url": "streaming URL",
"site": "Factory_1",
"stream_name": "camera_1",
"model_key": "yolo11n",
"notifications": {
"line_token_3": "language_3",
"line_token_4": "language_4"
},
"detect_with_server": false,
"expire_date": "No Expire Date",
"detection_items": {
"detect_no_safety_vest_or_helmet": true,
"detect_near_machinery_or_vehicle": false,
"detect_in_restricted_area": true
},
"work_start_hour": 0,
"work_end_hour": 24,
"store_in_redis": true
}
]
43 changes: 29 additions & 14 deletions main.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,6 @@
# Load environment variables
load_dotenv()

is_windows = os.name == 'nt'


class AppConfig(TypedDict, total=False):
"""
Expand All @@ -45,6 +43,9 @@ class AppConfig(TypedDict, total=False):
line_token: str | None
language: str | None
detection_items: dict[str, bool] | None
work_start_hour: int | None
work_end_hour: int | None
store_in_redis: bool


class MainApp:
Expand Down Expand Up @@ -82,13 +83,18 @@ def compute_config_hash(self, config: dict) -> str:
'stream_name': config.get('stream_name', 'prediction_visual'),
'notifications': config['notifications'],
'detect_with_server': config['detect_with_server'],
'expire_date': config.get('expire_date'),
'language': config.get('language'),
'detection_items': config.get('detection_items'),
'work_start_hour': config.get('work_start_hour'),
'work_end_hour': config.get('work_end_hour'),
'store_in_redis': config.get('store_in_redis', False),
}
return str(relevant_config) # Convert to string for hashing

async def reload_configurations(self):
async with self.lock:
if not is_windows:
redis_manager = RedisManager()
redis_manager = RedisManager()

self.logger.info('Reloading configurations...')
with open(self.config_file, encoding='utf-8') as file:
Expand Down Expand Up @@ -238,6 +244,9 @@ async def process_single_stream(
notifications: dict[str, str] | None = None,
detect_with_server: bool = False,
detection_items: dict[str, bool] | None = {},
work_start_hour: int = 7,
work_end_hour: int = 18,
store_in_redis: bool = False,
) -> None:
"""
Process a single video stream with hazard detection, notifications,
Expand All @@ -253,7 +262,7 @@ async def process_single_stream(
detect_with_server (bool): Whether to use server for detection.
detection_items (dict): Items to detect.
"""
if not is_windows:
if store_in_redis:
redis_manager = RedisManager()

# Initialise the stream capture object
Expand Down Expand Up @@ -297,7 +306,9 @@ async def process_single_stream(
detection_time = datetime.fromtimestamp(timestamp)

# Check if the current time is within working hours
is_working_hour = 7 <= detection_time.hour < 23
is_working_hour = (
work_start_hour <= detection_time.hour < work_end_hour
)

# Detection step
datas, _ = await live_stream_detector.generate_detections(frame)
Expand Down Expand Up @@ -359,7 +370,7 @@ async def process_single_stream(
frame_bytes = Utils.encode_frame(frame_with_detections)

# Store the frame bytes to Redis
if not is_windows:
if store_in_redis:
await redis_manager.store_to_redis(
site=site or 'default',
stream_name=stream_name,
Expand All @@ -383,7 +394,7 @@ async def process_single_stream(
await streaming_capture.release_resources()

# Close the Redis connection
if not is_windows:
if store_in_redis:
await redis_manager.close_connection()

gc.collect()
Expand All @@ -393,7 +404,7 @@ async def process_streams(self, config: AppConfig) -> None:
Process a video stream based on the given configuration.
Args:
config (StreamConfig): The configuration for the stream processing.
config (AppConfig): The configuration for the stream processing.
Returns:
None
Expand Down Expand Up @@ -423,6 +434,9 @@ async def process_streams(self, config: AppConfig) -> None:
stream_name = config.get('stream_name', 'prediction_visual')
detect_with_server = config.get('detect_with_server', False)
detection_items = config.get('detection_items', None)
store_in_redis = config.get('store_in_redis', False)
work_start_hour = config.get('work_start_hour', 7)
work_end_hour = config.get('work_end_hour', 18)

# Run hazard detection on a single video stream
await self.process_single_stream(
Expand All @@ -434,19 +448,20 @@ async def process_streams(self, config: AppConfig) -> None:
notifications=notifications,
detect_with_server=detect_with_server,
detection_items=detection_items,
work_start_hour=work_start_hour or 7,
work_end_hour=work_end_hour or 18,
store_in_redis=store_in_redis,
)
finally:
if not is_windows:
if config.get('store_in_redis', False):
redis_manager = RedisManager()
site = config.get('site') or 'default site'
stream_name = config.get(
'stream_name',
) or 'default stream name'

site = Utils.encode(site)
stream_name = Utils.encode(
stream_name,
)
stream_name = Utils.encode(stream_name)

key = f"stream_frame:{site}|{stream_name}"
await redis_manager.delete(key)
Expand Down Expand Up @@ -608,7 +623,7 @@ async def main():
print('\n[INFO] Received KeyboardInterrupt. Shutting down...')
finally:
# Perform necessary cleanup if needed
# if not is_windows:
# if store_in_redis:
# await redis_manager.close_connection()
# print('[INFO] Redis connection closed.')
print('[INFO] Application stopped.')
Expand Down

0 comments on commit dea495d

Please sign in to comment.