Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Motion detected message + picture in one mqtt publish #44

Closed
mxmaxime opened this issue Aug 7, 2020 · 0 comments · Fixed by #46
Closed

Motion detected message + picture in one mqtt publish #44

mxmaxime opened this issue Aug 7, 2020 · 0 comments · Fixed by #46
Assignees
Labels
bug Something isn't working
Projects
Milestone

Comments

@mxmaxime
Copy link
Collaborator

mxmaxime commented Aug 7, 2020

Limitation

When a motion is detected, we want to send the picture where it was detected. We use mqtt to send the picture as bytearray because we cannot send the picture with a JSON. We could convert the image as base64 to be able to send it with JSON, but it would be very inefficient. Basically, we can't send the bytearray into a JSON, or at least I didn't find the solution.

The issue

Otherwise I send two messages, one to say "someone is here" and one to send the picture. It's fine, but the first one create a database entry and the second one modifies it to add the picture path. We can have race condition here... The order can't be guarantee.

Or I can simply retry the second task if we don't found the database row. https://docs.celeryproject.org/en/stable/userguide/tasks.html#retrying

The solution

I have decided to change the workflow. When a picture is coming, we are saving it on local drive (and another in the future maybe...) and we are saving this file path in database without any link to motion detected. To find pictures "associated" with a motion detection even, we can select pictures based on the date +- 10s for instance.

Otherwise, to link the picture with the event, we would have this kind of code in the task:

@shared_task(name="security.camera_motion_detected")
def camera_motion_detected(device_id: str):
    try:
        camera_motion = alarm_models.CameraMotionDetected.objects.filter(picture_path__isnull=True).latest('created_at')
    except alarm_models.CameraMotionDetected.DoesNotExist as exc:
        raise self.retry(exc=exc)
    else:
        camera_motion.picture_path = picture_path
        camera_motion.save()

        messaging = Messaging()
        messaging.send_message(picture_path=picture_path)

First, it's ugly, just look at the except! And secondly, it's not reliable, we could associate a picture with the wrong event in the case where two (or more) devices detect motion and send pictures.

@mxmaxime mxmaxime added the bug Something isn't working label Aug 7, 2020
@mxmaxime mxmaxime self-assigned this Aug 7, 2020
@mxmaxime mxmaxime added this to To do in v0.1.0 via automation Aug 7, 2020
@mxmaxime mxmaxime added this to the First release milestone Aug 7, 2020
@mxmaxime mxmaxime closed this as completed Aug 9, 2020
v0.1.0 automation moved this from To do to Done Aug 9, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
No open projects
v0.1.0
  
Done
Development

Successfully merging a pull request may close this issue.

1 participant