nedo-vision-worker 1.3.0__tar.gz → 1.3.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/PKG-INFO +1 -1
- {nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/nedo_vision_worker/__init__.py +1 -1
- {nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/nedo_vision_worker/worker/PPEDetectionManager.py +65 -15
- {nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/nedo_vision_worker/worker/RestrictedAreaManager.py +63 -15
- {nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/nedo_vision_worker.egg-info/PKG-INFO +1 -1
- {nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/README.md +0 -0
- {nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/nedo_vision_worker/cli.py +0 -0
- {nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/nedo_vision_worker/config/ConfigurationManager.py +0 -0
- {nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/nedo_vision_worker/config/__init__.py +0 -0
- {nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/nedo_vision_worker/database/DatabaseManager.py +0 -0
- {nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/nedo_vision_worker/database/__init__.py +0 -0
- {nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/nedo_vision_worker/doctor.py +0 -0
- {nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/nedo_vision_worker/initializer/AppInitializer.py +0 -0
- {nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/nedo_vision_worker/initializer/__init__.py +0 -0
- {nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/nedo_vision_worker/models/__init__.py +0 -0
- {nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/nedo_vision_worker/models/ai_model.py +0 -0
- {nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/nedo_vision_worker/models/auth.py +0 -0
- {nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/nedo_vision_worker/models/config.py +0 -0
- {nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/nedo_vision_worker/models/dataset_source.py +0 -0
- {nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/nedo_vision_worker/models/logs.py +0 -0
- {nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/nedo_vision_worker/models/ppe_detection.py +0 -0
- {nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/nedo_vision_worker/models/ppe_detection_label.py +0 -0
- {nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/nedo_vision_worker/models/restricted_area_violation.py +0 -0
- {nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/nedo_vision_worker/models/user.py +0 -0
- {nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/nedo_vision_worker/models/worker_source.py +0 -0
- {nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/nedo_vision_worker/models/worker_source_pipeline.py +0 -0
- {nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/nedo_vision_worker/models/worker_source_pipeline_config.py +0 -0
- {nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/nedo_vision_worker/models/worker_source_pipeline_debug.py +0 -0
- {nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/nedo_vision_worker/models/worker_source_pipeline_detection.py +0 -0
- {nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/nedo_vision_worker/protos/AIModelService_pb2.py +0 -0
- {nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/nedo_vision_worker/protos/AIModelService_pb2_grpc.py +0 -0
- {nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/nedo_vision_worker/protos/DatasetSourceService_pb2.py +0 -0
- {nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/nedo_vision_worker/protos/DatasetSourceService_pb2_grpc.py +0 -0
- {nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/nedo_vision_worker/protos/HumanDetectionService_pb2.py +0 -0
- {nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/nedo_vision_worker/protos/HumanDetectionService_pb2_grpc.py +0 -0
- {nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/nedo_vision_worker/protos/PPEDetectionService_pb2.py +0 -0
- {nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/nedo_vision_worker/protos/PPEDetectionService_pb2_grpc.py +0 -0
- {nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/nedo_vision_worker/protos/VisionWorkerService_pb2.py +0 -0
- {nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/nedo_vision_worker/protos/VisionWorkerService_pb2_grpc.py +0 -0
- {nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/nedo_vision_worker/protos/WorkerSourcePipelineService_pb2.py +0 -0
- {nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/nedo_vision_worker/protos/WorkerSourcePipelineService_pb2_grpc.py +0 -0
- {nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/nedo_vision_worker/protos/WorkerSourceService_pb2.py +0 -0
- {nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/nedo_vision_worker/protos/WorkerSourceService_pb2_grpc.py +0 -0
- {nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/nedo_vision_worker/protos/__init__.py +0 -0
- {nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/nedo_vision_worker/repositories/AIModelRepository.py +0 -0
- {nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/nedo_vision_worker/repositories/DatasetSourceRepository.py +0 -0
- {nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/nedo_vision_worker/repositories/PPEDetectionRepository.py +0 -0
- {nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/nedo_vision_worker/repositories/RestrictedAreaRepository.py +0 -0
- {nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/nedo_vision_worker/repositories/WorkerSourcePipelineDebugRepository.py +0 -0
- {nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/nedo_vision_worker/repositories/WorkerSourcePipelineDetectionRepository.py +0 -0
- {nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/nedo_vision_worker/repositories/WorkerSourcePipelineRepository.py +0 -0
- {nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/nedo_vision_worker/repositories/WorkerSourceRepository.py +0 -0
- {nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/nedo_vision_worker/repositories/__init__.py +0 -0
- {nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/nedo_vision_worker/services/AIModelClient.py +0 -0
- {nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/nedo_vision_worker/services/ConnectionInfoClient.py +0 -0
- {nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/nedo_vision_worker/services/DatasetSourceClient.py +0 -0
- {nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/nedo_vision_worker/services/DirectDeviceToRTMPStreamer.py +0 -0
- {nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/nedo_vision_worker/services/FileToRTMPServer.py +0 -0
- {nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/nedo_vision_worker/services/GrpcClientBase.py +0 -0
- {nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/nedo_vision_worker/services/GrpcClientManager.py +0 -0
- {nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/nedo_vision_worker/services/GrpcConnection.py +0 -0
- {nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/nedo_vision_worker/services/ImageUploadClient.py +0 -0
- {nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/nedo_vision_worker/services/PPEDetectionClient.py +0 -0
- {nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/nedo_vision_worker/services/RTSPtoRTMPStreamer.py +0 -0
- {nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/nedo_vision_worker/services/RestrictedAreaClient.py +0 -0
- {nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/nedo_vision_worker/services/SharedDirectDeviceClient.py +0 -0
- {nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/nedo_vision_worker/services/SharedVideoStreamServer.py +0 -0
- {nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/nedo_vision_worker/services/SystemUsageClient.py +0 -0
- {nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/nedo_vision_worker/services/SystemWideDeviceCoordinator.py +0 -0
- {nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/nedo_vision_worker/services/VideoSharingDaemon.py +0 -0
- {nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/nedo_vision_worker/services/VideoStreamClient.py +0 -0
- {nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/nedo_vision_worker/services/WorkerSourceClient.py +0 -0
- {nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/nedo_vision_worker/services/WorkerSourcePipelineClient.py +0 -0
- {nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/nedo_vision_worker/services/WorkerSourceUpdater.py +0 -0
- {nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/nedo_vision_worker/services/WorkerStatusClient.py +0 -0
- {nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/nedo_vision_worker/services/__init__.py +0 -0
- {nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/nedo_vision_worker/util/EncoderSelector.py +0 -0
- {nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/nedo_vision_worker/util/FFmpegUtil.py +0 -0
- {nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/nedo_vision_worker/util/HardwareID.py +0 -0
- {nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/nedo_vision_worker/util/ImageUploader.py +0 -0
- {nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/nedo_vision_worker/util/Networking.py +0 -0
- {nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/nedo_vision_worker/util/PlatformDetector.py +0 -0
- {nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/nedo_vision_worker/util/SystemMonitor.py +0 -0
- {nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/nedo_vision_worker/util/VideoProbeUtil.py +0 -0
- {nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/nedo_vision_worker/util/__init__.py +0 -0
- {nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/nedo_vision_worker/worker/CoreActionWorker.py +0 -0
- {nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/nedo_vision_worker/worker/DataSenderWorker.py +0 -0
- {nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/nedo_vision_worker/worker/DataSyncWorker.py +0 -0
- {nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/nedo_vision_worker/worker/DatasetFrameSender.py +0 -0
- {nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/nedo_vision_worker/worker/DatasetFrameWorker.py +0 -0
- {nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/nedo_vision_worker/worker/PipelineActionWorker.py +0 -0
- {nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/nedo_vision_worker/worker/PipelineImageWorker.py +0 -0
- {nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/nedo_vision_worker/worker/PipelinePreviewWorker.py +0 -0
- {nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/nedo_vision_worker/worker/RabbitMQListener.py +0 -0
- {nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/nedo_vision_worker/worker/SystemUsageManager.py +0 -0
- {nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/nedo_vision_worker/worker/VideoStreamWorker.py +0 -0
- {nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/nedo_vision_worker/worker/WorkerManager.py +0 -0
- {nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/nedo_vision_worker/worker/__init__.py +0 -0
- {nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/nedo_vision_worker/worker_service.py +0 -0
- {nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/nedo_vision_worker.egg-info/SOURCES.txt +0 -0
- {nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/nedo_vision_worker.egg-info/dependency_links.txt +0 -0
- {nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/nedo_vision_worker.egg-info/entry_points.txt +0 -0
- {nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/nedo_vision_worker.egg-info/requires.txt +0 -0
- {nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/nedo_vision_worker.egg-info/top_level.txt +0 -0
- {nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/pyproject.toml +0 -0
- {nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/setup.cfg +0 -0
- {nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/setup.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: nedo-vision-worker
|
|
3
|
-
Version: 1.3.
|
|
3
|
+
Version: 1.3.3
|
|
4
4
|
Summary: Nedo Vision Worker Service Library for AI Vision Processing
|
|
5
5
|
Author-email: Willy Achmat Fauzi <willy.achmat@gmail.com>
|
|
6
6
|
Maintainer-email: Willy Achmat Fauzi <willy.achmat@gmail.com>
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import logging
|
|
2
|
+
import os
|
|
2
3
|
import threading
|
|
3
4
|
import time
|
|
4
5
|
from ..services.PPEDetectionClient import PPEDetectionClient
|
|
@@ -50,41 +51,90 @@ class PPEDetectionManager:
|
|
|
50
51
|
|
|
51
52
|
logger.info("📡 [APP] PPE detection monitoring started.")
|
|
52
53
|
|
|
53
|
-
def
|
|
54
|
+
def _calculate_fetch_size(self, pending_count: int) -> int:
|
|
54
55
|
"""
|
|
55
|
-
|
|
56
|
-
Conservative limits to prevent server overload.
|
|
56
|
+
Dynamically calculates how many records to fetch based on pending count.
|
|
57
57
|
|
|
58
58
|
Args:
|
|
59
59
|
pending_count (int): Number of pending detections
|
|
60
60
|
|
|
61
61
|
Returns:
|
|
62
|
-
int:
|
|
62
|
+
int: Number of records to fetch
|
|
63
63
|
"""
|
|
64
|
-
if pending_count
|
|
65
|
-
return 10
|
|
66
|
-
elif pending_count
|
|
67
|
-
return 30
|
|
68
|
-
elif pending_count
|
|
69
|
-
return 50
|
|
64
|
+
if pending_count <= 50:
|
|
65
|
+
return min(pending_count, 10)
|
|
66
|
+
elif pending_count <= 200:
|
|
67
|
+
return min(pending_count, 30)
|
|
68
|
+
elif pending_count <= 1000:
|
|
69
|
+
return min(pending_count, 50)
|
|
70
70
|
else:
|
|
71
|
-
return 100
|
|
71
|
+
return min(pending_count, 100)
|
|
72
|
+
|
|
73
|
+
def _calculate_batch_by_size(self, all_detections: list, max_size_mb: int = 40) -> list:
|
|
74
|
+
"""
|
|
75
|
+
Calculates batch based on actual image file sizes to stay within gRPC limit.
|
|
76
|
+
|
|
77
|
+
Args:
|
|
78
|
+
all_detections (list): All pending detections
|
|
79
|
+
max_size_mb (int): Maximum batch size in MB (default 40MB for 50MB limit with margin)
|
|
80
|
+
|
|
81
|
+
Returns:
|
|
82
|
+
list: Detections that fit within size limit
|
|
83
|
+
"""
|
|
84
|
+
import os
|
|
85
|
+
|
|
86
|
+
batch = []
|
|
87
|
+
total_size = 0
|
|
88
|
+
max_size_bytes = max_size_mb * 1024 * 1024
|
|
89
|
+
|
|
90
|
+
for detection in all_detections:
|
|
91
|
+
try:
|
|
92
|
+
image_size = os.path.getsize(detection['image']) if os.path.exists(detection['image']) else 0
|
|
93
|
+
tile_size = os.path.getsize(detection['image_tile']) if os.path.exists(detection['image_tile']) else 0
|
|
94
|
+
detection_size = image_size + tile_size
|
|
95
|
+
|
|
96
|
+
if total_size + detection_size > max_size_bytes:
|
|
97
|
+
if batch:
|
|
98
|
+
break
|
|
99
|
+
else:
|
|
100
|
+
logger.warning(f"⚠️ Single detection exceeds {max_size_mb}MB, skipping")
|
|
101
|
+
continue
|
|
102
|
+
|
|
103
|
+
batch.append(detection)
|
|
104
|
+
total_size += detection_size
|
|
105
|
+
|
|
106
|
+
except Exception as e:
|
|
107
|
+
logger.error(f"❌ Error checking file size: {e}")
|
|
108
|
+
continue
|
|
109
|
+
|
|
110
|
+
return batch
|
|
72
111
|
|
|
73
112
|
def send_ppe_detection_batch(self):
|
|
74
|
-
"""Sends a batch of collected PPE detection data to the server with dynamic
|
|
113
|
+
"""Sends a batch of collected PPE detection data to the server with dynamic size-based batching."""
|
|
75
114
|
try:
|
|
76
115
|
pending_count = self.ppe_detection_repo.get_total_pending_count()
|
|
77
116
|
|
|
78
117
|
if pending_count == 0:
|
|
79
118
|
return
|
|
80
119
|
|
|
81
|
-
|
|
82
|
-
|
|
120
|
+
fetch_size = self._calculate_fetch_size(pending_count)
|
|
121
|
+
all_detections = self.ppe_detection_repo.get_latest_detections(fetch_size)
|
|
122
|
+
|
|
123
|
+
if not all_detections:
|
|
124
|
+
return
|
|
125
|
+
|
|
126
|
+
self.ppe_detection_data = self._calculate_batch_by_size(all_detections)
|
|
83
127
|
|
|
84
128
|
if not self.ppe_detection_data:
|
|
129
|
+
logger.warning("⚠️ [APP] No valid detections within size limit")
|
|
85
130
|
return
|
|
86
131
|
|
|
87
|
-
|
|
132
|
+
batch_size_mb = sum(
|
|
133
|
+
os.path.getsize(d['image']) + os.path.getsize(d['image_tile'])
|
|
134
|
+
for d in self.ppe_detection_data if os.path.exists(d['image']) and os.path.exists(d['image_tile'])
|
|
135
|
+
) / (1024 * 1024)
|
|
136
|
+
|
|
137
|
+
logger.info(f"📤 [APP] Sending {len(self.ppe_detection_data)} PPE detections (~{batch_size_mb:.1f}MB, {pending_count} pending)")
|
|
88
138
|
|
|
89
139
|
response = self.ppe_detection_client.send_upsert_batch(
|
|
90
140
|
worker_id=self.worker_id,
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import logging
|
|
2
|
+
import os
|
|
2
3
|
import threading
|
|
3
4
|
import time
|
|
4
5
|
|
|
@@ -50,41 +51,88 @@ class RestrictedAreaManager:
|
|
|
50
51
|
|
|
51
52
|
logger.info("📡 [APP] Restricted area violation monitoring started.")
|
|
52
53
|
|
|
53
|
-
def
|
|
54
|
+
def _calculate_fetch_size(self, pending_count: int) -> int:
|
|
54
55
|
"""
|
|
55
|
-
|
|
56
|
-
Conservative limits to prevent server overload.
|
|
56
|
+
Dynamically calculates how many records to fetch based on pending count.
|
|
57
57
|
|
|
58
58
|
Args:
|
|
59
59
|
pending_count (int): Number of pending violations
|
|
60
60
|
|
|
61
61
|
Returns:
|
|
62
|
-
int:
|
|
62
|
+
int: Number of records to fetch
|
|
63
63
|
"""
|
|
64
|
-
if pending_count
|
|
65
|
-
return 10
|
|
66
|
-
elif pending_count
|
|
67
|
-
return 30
|
|
68
|
-
elif pending_count
|
|
69
|
-
return 50
|
|
64
|
+
if pending_count <= 50:
|
|
65
|
+
return min(pending_count, 10)
|
|
66
|
+
elif pending_count <= 200:
|
|
67
|
+
return min(pending_count, 30)
|
|
68
|
+
elif pending_count <= 1000:
|
|
69
|
+
return min(pending_count, 50)
|
|
70
70
|
else:
|
|
71
|
-
return 100
|
|
71
|
+
return min(pending_count, 100)
|
|
72
|
+
|
|
73
|
+
def _calculate_batch_by_size(self, all_violations: list, max_size_mb: int = 40) -> list:
|
|
74
|
+
"""
|
|
75
|
+
Calculates batch based on actual image file sizes to stay within gRPC limit.
|
|
76
|
+
|
|
77
|
+
Args:
|
|
78
|
+
all_violations (list): All pending violations
|
|
79
|
+
max_size_mb (int): Maximum batch size in MB (default 40MB for 50MB limit with margin)
|
|
80
|
+
|
|
81
|
+
Returns:
|
|
82
|
+
list: Violations that fit within size limit
|
|
83
|
+
"""
|
|
84
|
+
batch = []
|
|
85
|
+
total_size = 0
|
|
86
|
+
max_size_bytes = max_size_mb * 1024 * 1024
|
|
87
|
+
|
|
88
|
+
for violation in all_violations:
|
|
89
|
+
try:
|
|
90
|
+
image_size = os.path.getsize(violation['image']) if os.path.exists(violation['image']) else 0
|
|
91
|
+
tile_size = os.path.getsize(violation['image_tile']) if os.path.exists(violation['image_tile']) else 0
|
|
92
|
+
violation_size = image_size + tile_size
|
|
93
|
+
|
|
94
|
+
if total_size + violation_size > max_size_bytes:
|
|
95
|
+
if batch:
|
|
96
|
+
break
|
|
97
|
+
else:
|
|
98
|
+
logger.warning(f"⚠️ Single violation exceeds {max_size_mb}MB, skipping")
|
|
99
|
+
continue
|
|
100
|
+
|
|
101
|
+
batch.append(violation)
|
|
102
|
+
total_size += violation_size
|
|
103
|
+
|
|
104
|
+
except Exception as e:
|
|
105
|
+
logger.error(f"❌ Error checking file size: {e}")
|
|
106
|
+
continue
|
|
107
|
+
|
|
108
|
+
return batch
|
|
72
109
|
|
|
73
110
|
def send_violation_batch(self):
|
|
74
|
-
"""Sends a batch of collected violation data to the server with dynamic
|
|
111
|
+
"""Sends a batch of collected violation data to the server with dynamic size-based batching."""
|
|
75
112
|
try:
|
|
76
113
|
pending_count = self.repo.get_total_pending_count()
|
|
77
114
|
|
|
78
115
|
if pending_count == 0:
|
|
79
116
|
return
|
|
80
117
|
|
|
81
|
-
|
|
82
|
-
|
|
118
|
+
fetch_size = self._calculate_fetch_size(pending_count)
|
|
119
|
+
all_violations = self.repo.get_latest_violations(fetch_size)
|
|
120
|
+
|
|
121
|
+
if not all_violations:
|
|
122
|
+
return
|
|
123
|
+
|
|
124
|
+
self.violations_data = self._calculate_batch_by_size(all_violations)
|
|
83
125
|
|
|
84
126
|
if not self.violations_data:
|
|
127
|
+
logger.warning("⚠️ [APP] No valid violations within size limit")
|
|
85
128
|
return
|
|
86
129
|
|
|
87
|
-
|
|
130
|
+
batch_size_mb = sum(
|
|
131
|
+
os.path.getsize(v['image']) + os.path.getsize(v['image_tile'])
|
|
132
|
+
for v in self.violations_data if os.path.exists(v['image']) and os.path.exists(v['image_tile'])
|
|
133
|
+
) / (1024 * 1024)
|
|
134
|
+
|
|
135
|
+
logger.info(f"📤 [APP] Sending {len(self.violations_data)} violations (~{batch_size_mb:.1f}MB, {pending_count} pending)")
|
|
88
136
|
|
|
89
137
|
response = self.client.send_upsert_batch(
|
|
90
138
|
worker_id=self.worker_id,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: nedo-vision-worker
|
|
3
|
-
Version: 1.3.
|
|
3
|
+
Version: 1.3.3
|
|
4
4
|
Summary: Nedo Vision Worker Service Library for AI Vision Processing
|
|
5
5
|
Author-email: Willy Achmat Fauzi <willy.achmat@gmail.com>
|
|
6
6
|
Maintainer-email: Willy Achmat Fauzi <willy.achmat@gmail.com>
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/nedo_vision_worker/database/DatabaseManager.py
RENAMED
|
File without changes
|
{nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/nedo_vision_worker/database/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/nedo_vision_worker/initializer/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/nedo_vision_worker/models/dataset_source.py
RENAMED
|
File without changes
|
|
File without changes
|
{nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/nedo_vision_worker/models/ppe_detection.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/nedo_vision_worker/models/worker_source.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/nedo_vision_worker/repositories/__init__.py
RENAMED
|
File without changes
|
{nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/nedo_vision_worker/services/AIModelClient.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/nedo_vision_worker/services/GrpcClientBase.py
RENAMED
|
File without changes
|
|
File without changes
|
{nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/nedo_vision_worker/services/GrpcConnection.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/nedo_vision_worker/services/__init__.py
RENAMED
|
File without changes
|
{nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/nedo_vision_worker/util/EncoderSelector.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/nedo_vision_worker/util/ImageUploader.py
RENAMED
|
File without changes
|
|
File without changes
|
{nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/nedo_vision_worker/util/PlatformDetector.py
RENAMED
|
File without changes
|
{nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/nedo_vision_worker/util/SystemMonitor.py
RENAMED
|
File without changes
|
{nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/nedo_vision_worker/util/VideoProbeUtil.py
RENAMED
|
File without changes
|
|
File without changes
|
{nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/nedo_vision_worker/worker/CoreActionWorker.py
RENAMED
|
File without changes
|
{nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/nedo_vision_worker/worker/DataSenderWorker.py
RENAMED
|
File without changes
|
{nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/nedo_vision_worker/worker/DataSyncWorker.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/nedo_vision_worker/worker/RabbitMQListener.py
RENAMED
|
File without changes
|
|
File without changes
|
{nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/nedo_vision_worker/worker/VideoStreamWorker.py
RENAMED
|
File without changes
|
{nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/nedo_vision_worker/worker/WorkerManager.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/nedo_vision_worker.egg-info/SOURCES.txt
RENAMED
|
File without changes
|
|
File without changes
|
{nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/nedo_vision_worker.egg-info/entry_points.txt
RENAMED
|
File without changes
|
{nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/nedo_vision_worker.egg-info/requires.txt
RENAMED
|
File without changes
|
{nedo_vision_worker-1.3.0 → nedo_vision_worker-1.3.3}/nedo_vision_worker.egg-info/top_level.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|