diff --git a/rosys/rosys.py b/rosys/rosys.py index 52997403..fb6bab5e 100644 --- a/rosys/rosys.py +++ b/rosys/rosys.py @@ -6,6 +6,7 @@ import signal import threading import time as pytime +import warnings from collections.abc import Awaitable, Callable from dataclasses import dataclass from typing import Any, ClassVar, Literal @@ -21,6 +22,8 @@ from .helpers import is_test as is_test_ from .persistence.registry import backup, restore, sync_backup +warnings.filterwarnings('once', category=DeprecationWarning, module='rosys') + log = logging.getLogger('rosys.core') config = Config() diff --git a/rosys/vision/detector.py b/rosys/vision/detector.py index b08fa095..f2759b2d 100644 --- a/rosys/vision/detector.py +++ b/rosys/vision/detector.py @@ -9,7 +9,6 @@ from ..event import Event from .detections import Category, Detections from .image import Image -from .uploads import Uploads class Autoupload(Enum): @@ -93,7 +92,6 @@ def __init__(self, *, name: str | None = None) -> None: """detection on an image is completed (argument: image)""" self.log = logging.getLogger('rosys.detector') - self.uploads = Uploads() @abc.abstractmethod async def detect(self, diff --git a/rosys/vision/detector_hardware.py b/rosys/vision/detector_hardware.py index 0394d05f..c1b49689 100644 --- a/rosys/vision/detector_hardware.py +++ b/rosys/vision/detector_hardware.py @@ -1,5 +1,5 @@ import asyncio -from datetime import datetime, timedelta +from datetime import datetime from typing import Any, Literal import socketio @@ -46,22 +46,17 @@ def on_sio_disconnect() -> None: def on_sio_connect_error(err) -> None: self.log.warning('sio connect error on %s: %s', port, err) - rosys.on_repeat(self.step, 1.0) + rosys.on_repeat(self._ensure_connection, 10.0) @property def is_connected(self) -> bool: return self.sio.connected - async def step(self) -> None: + async def _ensure_connection(self) -> None: if not self.is_connected: self.log.info('trying reconnect %s', self.name) if not await self.connect(): self.log.error('connection to %s at port %s failed; trying again', self.name, self.port) - await rosys.sleep(3.0) - return - - await self.try_start_one_upload() - await self.upload_priority_queue() async def connect(self) -> bool: try: @@ -76,25 +71,6 @@ async def connect(self) -> bool: async def disconnect(self) -> None: await self.sio.disconnect() - async def try_start_one_upload(self) -> None: - if datetime.now() < self.uploads.last_upload + timedelta(minutes=self.uploads.minimal_minutes_between_uploads): - return - - upload_images = self.uploads.get_queued() - if upload_images: - rosys.background_tasks.create(self.upload(upload_images[0]), name='upload_image') - self.uploads.queue.clear() # old images should not be uploaded later when the robot is inactive - self.uploads.last_upload = datetime.now() - - async def upload_priority_queue(self) -> None: - upload_images = self.uploads.get_priority_queued() - if upload_images: - async def upload_priority_images(): - for image in upload_images: - await self.upload(image) - rosys.background_tasks.create(upload_priority_images(), name='upload_priority_images') - self.uploads.priority_queue.clear() - async def upload(self, image: Image, *, @@ -125,7 +101,6 @@ async def upload(self, detections_dict['point_detections'] = detections_dict.pop('points') detections_dict['segmentation_detections'] = detections_dict.pop('segmentations') data_dict['detections'] = detections_dict - data_dict['tags'] = list(image.tags.union(tags)) data_dict['source'] = source data_dict['creation_date'] = _creation_date_to_isoformat(creation_date) await self.sio.emit('upload', data_dict) diff --git a/rosys/vision/detector_simulation.py b/rosys/vision/detector_simulation.py index 370d0e50..61739fd3 100644 --- a/rosys/vision/detector_simulation.py +++ b/rosys/vision/detector_simulation.py @@ -51,12 +51,6 @@ def __init__(self, self.simulated_objects: list[SimulatedObject] = [] self.detection_delay = detection_delay - rosys.on_repeat(self.step, 0.1) - - def step(self) -> None: - self.uploads.queue.clear() - self.uploads.priority_queue.clear() - async def detect(self, image: Image, *, diff --git a/rosys/vision/image.py b/rosys/vision/image.py index ed52251d..2a09f53c 100644 --- a/rosys/vision/image.py +++ b/rosys/vision/image.py @@ -1,5 +1,6 @@ from __future__ import annotations +import warnings from dataclasses import dataclass, field from typing import ClassVar @@ -34,6 +35,11 @@ class Image: DEFAULT_PLACEHOLDER_SIZE: ClassVar[tuple[int, int]] = (320, 240) + def __post_init__(self) -> None: + if self.tags: + warnings.warn('The "tags" field is deprecated and will be removed in a future version.', + DeprecationWarning, stacklevel=2) + @property def detections(self) -> Detections | None: if not self._detections: diff --git a/rosys/vision/uploads.py b/rosys/vision/uploads.py deleted file mode 100644 index 795524fa..00000000 --- a/rosys/vision/uploads.py +++ /dev/null @@ -1,27 +0,0 @@ -from dataclasses import dataclass, field -from datetime import datetime - -from rosys import persistence - -from .image import Image - - -@dataclass(slots=True, kw_only=True) -class Uploads: - minimal_minutes_between_uploads: float = 1.0 - last_upload: datetime = field(default_factory=lambda: datetime.fromtimestamp(0)) - queue: dict[str, Image] = field(default_factory=dict, metadata=persistence.exclude) - priority_queue: dict[str, Image] = field(default_factory=dict, metadata=persistence.exclude) - - def mark(self, image: Image, *, force: bool = False) -> None: - """Mark an image for upload. Set force=True to circumvent minimal_minutes_between_uploads.""" - if force: - self.priority_queue[image.id] = image - else: - self.queue[image.id] = image - - def get_queued(self) -> list[Image]: - return [image for image in self.queue.values() if image.data] - - def get_priority_queued(self) -> list[Image]: - return [image for image in self.priority_queue.values() if image.data]