Skip to content

Commit

Permalink
fix camera manager taking more pictures than what was in the config
Browse files Browse the repository at this point in the history
  • Loading branch information
bojeanson committed Feb 12, 2025
1 parent 992bdb6 commit 6ac1570
Show file tree
Hide file tree
Showing 15 changed files with 284 additions and 25 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ def __init__(self):
self._load_all_configs()

def _load_all_configs(self) -> StationConfig:
self._station_configs = {}
if not self._config_dir.exists():
self._logger.warning("No config directory found, creating it.")
self._config_dir.mkdir(parents=True)
Expand Down Expand Up @@ -62,7 +63,10 @@ def set_config(self, new_station_config: StationConfig):
def get_config(self) -> Optional[StationConfig]:
return self._station_configs.get(self._active_station_name)

def get_all_configs(self) -> Dict[str, StationConfig]:
def get_all_configs(self, reload: Optional[bool] = False) -> Dict[str, StationConfig]:
# TODO: test me
if reload:
self._load_all_configs()
return self._station_configs

def get_all_config_names(self) -> List[str]:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,3 @@ class ICamera(ABC):
def capture(self) -> Image:
pass

@abstractmethod
def get_camera_config(self) -> CameraConfig:
pass
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
from typing import Dict, List
from uuid import UUID

from fastapi import HTTPException

from edge_orchestrator.domain.models.item import Item
from edge_orchestrator.domain.models.storage.storage_config import StorageConfig
from edge_orchestrator.domain.ports.binary_storage.i_binary_storage import (
Expand Down Expand Up @@ -41,6 +43,9 @@ def get_item_binary_names(self, item_id: UUID) -> List[str]:

def get_item_binary(self, item_id: UUID, camera_id: str) -> bytes:
filepath = self._get_storing_path(item_id) / f"{camera_id}.jpg"
# TODO: test with non existing item binary
if not filepath.exists():
raise HTTPException(status_code=400, detail=f"The item {item_id} has no binary for {camera_id}")
with filepath.open("rb") as f:
return f.read()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,10 @@ def __init__(self, camera_factory: ICameraFactory):
self._camera_factory = camera_factory
self._cameras: Dict[str, ICamera] = {}
self._logger = logging.getLogger(__name__)
self._camera_configs: Dict[str, CameraConfig] = {}

def create_cameras(self, station_config: StationConfig):
self._camera_configs = station_config.camera_configs
for camera_id, camera_config in station_config.camera_configs.items():
if camera_id not in self._cameras or camera_config.recreate_me:
camera = self._camera_factory.create_camera(camera_config)
Expand All @@ -31,8 +33,8 @@ def take_pictures(self, item: Item):

binaries: Dict[str, bytes] = {}
cameras_metadata: Dict[str, CameraConfig] = {}
for camera_id, camera in self._cameras.items():
binaries[camera_id] = camera.capture()
cameras_metadata[camera_id] = camera.get_camera_config()
for camera_id, camera_config in self._camera_configs.items():
binaries[camera_id] = self._cameras[camera_id].capture()
cameras_metadata[camera_id] = camera_config
item.binaries = binaries
item.cameras_metadata = cameras_metadata
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,6 @@ def capture(self) -> Image:
random_image_path = self._select_random_image()
return Image(image_bytes=random_image_path.open("rb").read())

def get_camera_config(self) -> CameraConfig:
return self._camera_config

def _select_random_image(self) -> Path:
source = self._camera_config.source_directory
selected_images = []
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,3 @@ def capture(self) -> Image:
self.pi_camera.capture(stream, "jpeg")
stream.seek(0)
return Image(image_bytes=stream.read())

def get_camera_config(self) -> CameraConfig:
return self._camera_config
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,3 @@ def capture(self) -> Image:
cmd_feedback = subprocess.run([cmd], shell=True)
self._logger.info(f"Camera exit code: {cmd_feedback.returncode}")
return Image(image_bytes=Path(img_save_path).open("rb").read())

def get_camera_config(self) -> CameraConfig:
return self._camera_config
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,3 @@ def capture(self, attempt=0) -> Image:
exit_code, img_encode = cv2.imencode(".jpg", frame_rgb)
img_as_array = np.array(img_encode)
return Image(image_bytes=img_as_array.tobytes())

def get_camera_config(self) -> CameraConfig:
return self._camera_config
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from pathlib import Path
from uuid import UUID

from fastapi import HTTPException
from pydantic import ValidationError

from edge_orchestrator.domain.models.item import Item
Expand All @@ -27,6 +28,9 @@ def save_item_metadata(self, item: Item):

def get_item_metadata(self, item_id: UUID) -> Item:
filepath = self._get_storing_path(item_id)
# TODO: test with non existing item metadata
if not filepath.exists():
raise HTTPException(status_code=400, detail=f"The item {item_id} has no metadata")
with filepath.open("r") as f:
metadata = json.load(f)
return Item(**metadata)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,9 @@ def set_config(station_name: Optional[str] = None, station_config: Optional[Stat
return manager.get_config()


def get_all_configs() -> Dict[str, StationConfig]:
def get_all_configs(reload: Optional[bool]= False) -> Dict[str, StationConfig]:
manager = ConfigManager()
configs = manager.get_all_configs()
configs = manager.get_all_configs(reload)
if not configs:
raise HTTPException(status_code=400, detail="No existing configuration")
return configs
Expand Down
78 changes: 78 additions & 0 deletions edge_orchestrator/tests/config/config_1.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
{
"station_name": "config_1",
"camera_configs": {
"camera_1": {
"camera_id": "camera_1",
"camera_type": "fake",
"source_directory": "fake_images",
"position": "front",
"model_forwarder_config": {
"model_name": "fake_model",
"model_type": "classification",
"expected_image_resolution": {
"width": 224,
"height": 224
},
"model_version": "1",
"class_names": [
"OK",
"KO"
],
"recreate_me": false,
"model_id": "fake_model_classification_1"
},
"camera_rule_config": {
"camera_rule_type": "expected_label_rule",
"expected_class": "OK",
"recreate_me": false
},
"recreate_me": false
},
"camera_2": {
"camera_id": "camera_2",
"camera_type": "fake",
"source_directory": "fake_images",
"position": "front",
"model_forwarder_config": {
"model_name": "fake_model",
"model_type": "object_detection",
"expected_image_resolution": {
"width": 224,
"height": 224
},
"model_version": "1",
"class_names": [
"OK",
"KO"
],
"recreate_me": false,
"model_id": "fake_model_object_detection_1"
},
"camera_rule_config": {
"camera_rule_type": "min_nb_objects_rule",
"class_to_detect": "OK",
"threshold": 1,
"recreate_me": false
},
"recreate_me": false
}
},
"binary_storage_config": {
"storage_type": "filesystem",
"target_directory": "data_storage",
"prefix": "bapo_workstation",
"recreate_me": false
},
"metadata_storage_config": {
"storage_type": "filesystem",
"target_directory": "data_storage",
"prefix": "bapo_workstation",
"recreate_me": false
},
"item_rule_config": {
"item_rule_type": "min_threshold_ratio_rule",
"expected_decision": "OK",
"threshold": 1,
"recreate_me": false
}
}
106 changes: 106 additions & 0 deletions edge_orchestrator/tests/config/config_2.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
{
"station_name": "config_2",
"camera_configs": {
"camera_1": {
"camera_id": "camera_1",
"camera_type": "fake",
"source_directory": "fake_images",
"position": "front",
"model_forwarder_config": {
"model_name": "fake_model",
"model_type": "classification",
"expected_image_resolution": {
"width": 224,
"height": 224
},
"model_version": "1",
"class_names": [
"OK",
"KO"
],
"recreate_me": false,
"model_id": "fake_model_classification_1"
},
"camera_rule_config": {
"camera_rule_type": "expected_label_rule",
"expected_class": "OK",
"recreate_me": false
},
"recreate_me": false
},
"camera_2": {
"camera_id": "camera_2",
"camera_type": "fake",
"source_directory": "fake_images",
"position": "front",
"model_forwarder_config": {
"model_name": "fake_model",
"model_type": "object_detection",
"expected_image_resolution": {
"width": 224,
"height": 224
},
"model_version": "1",
"class_names": [
"OK",
"KO"
],
"recreate_me": false,
"model_id": "fake_model_object_detection_1"
},
"camera_rule_config": {
"camera_rule_type": "min_nb_objects_rule",
"class_to_detect": "OK",
"threshold": 1,
"recreate_me": false
},
"recreate_me": false
},
"camera_3": {
"camera_id": "camera_3",
"camera_type": "fake",
"source_directory": "fake_images",
"position": "front",
"model_forwarder_config": {
"model_name": "fake_model",
"model_type": "object_detection",
"expected_image_resolution": {
"width": 224,
"height": 224
},
"model_version": "1",
"class_names": [
"OK",
"KO"
],
"recreate_me": false,
"model_id": "fake_model_object_detection_1"
},
"camera_rule_config": {
"camera_rule_type": "max_nb_objects_rule",
"class_to_detect": "OK",
"threshold": 2,
"recreate_me": false
},
"recreate_me": false
}
},
"binary_storage_config": {
"storage_type": "filesystem",
"target_directory": "data_storage",
"prefix": "bapo_workstation",
"recreate_me": false
},
"metadata_storage_config": {
"storage_type": "filesystem",
"target_directory": "data_storage",
"prefix": "bapo_workstation",
"recreate_me": false
},
"item_rule_config": {
"item_rule_type": "min_threshold_ratio_rule",
"expected_decision": "OK",
"threshold": 1,
"recreate_me": false
}
}
78 changes: 78 additions & 0 deletions edge_orchestrator/tests/config/config_3.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
{
"station_name": "config_3",
"camera_configs": {
"camera_1": {
"camera_id": "camera_1",
"camera_type": "fake",
"source_directory": "fake_images",
"position": "front",
"model_forwarder_config": {
"model_name": "pin_detection",
"model_type": "classification",
"expected_image_resolution": {
"width": 224,
"height": 224
},
"model_version": "1",
"class_names": [
"OK",
"KO"
],
"model_serving_url": "http://0.0.0.0:8501/",
"recreate_me": false,
"model_id": "pin_detection_classification_1"
},
"camera_rule_config": {
"camera_rule_type": "expected_label_rule",
"expected_class": "OK",
"recreate_me": false
},
"recreate_me": false
},
"camera_2": {
"camera_id": "camera_2",
"camera_type": "fake",
"source_directory": "fake_images",
"position": "front",
"model_forwarder_config": {
"model_name": "mobilenet_ssd_v2_coco",
"model_type": "object_detection",
"expected_image_resolution": {
"width": 300,
"height": 300
},
"model_version": "1",
"class_names": [],
"class_names_filepath": "model_labels/imagenet_labels.txt",
"model_serving_url": "http://0.0.0.0:8501/",
"recreate_me": false,
"model_id": "mobilenet_ssd_v2_coco_object_detection_1"
},
"camera_rule_config": {
"camera_rule_type": "min_nb_objects_rule",
"class_to_detect": "OK",
"threshold": 1,
"recreate_me": false
},
"recreate_me": false
}
},
"binary_storage_config": {
"storage_type": "filesystem",
"target_directory": "data_storage",
"prefix": "bapo_workstation",
"recreate_me": false
},
"metadata_storage_config": {
"storage_type": "filesystem",
"target_directory": "data_storage",
"prefix": "bapo_workstation",
"recreate_me": false
},
"item_rule_config": {
"item_rule_type": "min_threshold_ratio_rule",
"expected_decision": "OK",
"threshold": 1,
"recreate_me": false
}
}
Loading

0 comments on commit 6ac1570

Please sign in to comment.