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

Feature Request: onDingDetected #50

Closed
tsightler opened this issue Jul 3, 2019 · 5 comments
Closed

Feature Request: onDingDetected #50

tsightler opened this issue Jul 3, 2019 · 5 comments

Comments

@tsightler
Copy link
Collaborator

tsightler commented Jul 3, 2019

So I've been working on adding camera support to ring-mqtt and perhaps it's just my inexperience, but I'm finding it confusing to work with cameras because it seems like there are so many different ways to get state for various things.

I've worked out that I can subscribe to onData and get state for lights and siren, which is great and simple. I can subscribe to onMotionDetected, and get simple true/false notifications when motion events start and end, OK, simple enough.

However, dings, i.e. doorbell presses. Here it seems that there's no single event to subscribe. Yes, I can subcribe to get a "ding" event, but then how to I monitor for when a "ding" even is over? Of course I can just start an event and time it in my own code, but it just seems strange compared to the rest of the API. I think it would be really nice of there was an "onDingDetected" observable that behaved with simple true/false similar to motion.

Now perhaps you're just exposing the way ding vs motion events work from the Ring API perspective, in which case I understand if you wouldn't want to implement this at the API level, I'll do it in my app, no problem, but I thought I'd put it out there. Besides, maybe you'll just tell me I'm doing it totally wrong and teach me something, and that's fine too!

@dgreif
Copy link
Owner

dgreif commented Jul 3, 2019

@tsightler I think you have a really good understanding of how everything is currently exposed, nice work! There is definitely a subtle difference between the doorbell presses and the motion events. For motion, I'm leaving the dings around for 65 seconds, and allowing for overlap between events. This is to prevent multiple motion events triggering in my homebridge plugin if there is constant motion for 2+ minutes. Whether that is right or not..that's up for debate. No one has gotten this deep into the code to have a discussion with.

Doorbell presses on the other hand, I handle as a singular event. Every time the doorbell is pressed (aka a ding with kind: 'ding' happens), I want to know about it and tell my homebridge plugin to create an event. This event is exposed via camera.onDoorbellPressed. From the homebridge perspective there is no duration to these events. They occur, and a notification pops via HomeKit. Unlike motion, there is no long lived status that say the doorbell is currently pressed or not pressed. That's my rational behind my implementation, but I have no idea if MQTT works the same way. If you need long-lived doorbell events, you can copy the implementation from onMotionDetected. Something like this:

import {  distinctUntilChanged,  map,  publishReplay, refCount } from 'rxjs/operators'

const camera = cameras[0]
const onActiveDoorbellPress = camera.onActiveDings.pipe(
    map(dings => dings.some(ding => ding.motion || ding.kind === 'motion')),
    distinctUntilChanged(),
    publishReplay(1),
    refCount()
  )

The downside for you here is you will need to add rxjs as a dependency in your repo to get those operators. Let me know what you decide on the single event vs long-lived doorbell press boolean. I can add onActiveDoorbellPress (or whatever you think it should be called) if you decide you want to go that route.

@tsightler
Copy link
Collaborator Author

So i guess my opinion is probably colored by the way the Ring component for Home Assistant behaves and how the Ring app behaves.

Based on what it seems, dings have a duration as they even have a duration property. The Home Assistant component seems to use this as the duration of the ding, whether motion or doorbell press. It seems the ding duration is 180 seconds and thats the behavior I feel like i see in both Home Assistant component and the Ring app, both a ding and motion are dismissed after 3 minutes.

However, i haven't really looked at the code for Home Assistant, I'm mostly inferring based on observed behavior and the fact that it seems to match the duration field on the ding. I'll look at the actual code when i get back to my computer.

I have no real issue coding this behavior into my script, but i was somewhat thinking the API might make it easier to consume in a standard way. I'll investigate it a little more though because i could be completely wrong.

@dgreif
Copy link
Owner

dgreif commented Jul 4, 2019

@tsightler thanks for the additional background info. I looked at the dings a little bit and it looks like you are correct, the expires_in field is ~180 for both motion and doorbell presses. The only hesitation I have about this is that my gut tells me the 180s is an expiration for the SIP connection details (although I have seen other threads that say those expire in ~15s). It might be worth doing some testing to see what the smallest time gap is you can get between two motion events on a single camera. I agree that it is worth adding it to the API if we decide that 180s is the actual duration of the events from Ring's perspective, and it's an easy change on my end. Unfortunately I'm going to be fairly tied up until the middle of next week. Let me know if you get a chance to test out the Ring events and see how long there is between them.

@tsightler
Copy link
Collaborator Author

I've tried to test this and, at least on my devices, (I have a Doorbell Pro, a Floodlight cam, and two Stickup Cams) it seems like I can only get a "ding" every 60 seconds at most. If I ring the doorbell over and over I don't get a new event until ~60 seconds and the same with motion.

After playing with this a little it turns out I was able to write a pretty simple function that gives me the behavior I want just by subscribing to onNewDing, so perhaps this is not big deal.

However, I did verify that the Home Assistant seems to use the full 180 seconds for a "ding", here's some event log output from my Home Assistant install for doorbell press events:

8:35 PM Front Doorbell Ding turned off
8:32 PM Front Doorbell Ding turned on
7:37 PM Front Doorbell Ding turned off
7:34 PM Front Doorbell Ding turned on
11:42 AM Front Doorbell Ding turned off
11:39 AM Front Doorbell Ding turned on

And a similar output for motion events:

8:47 PM Front Doorbell Motion turned off
8:44 PM Front Doorbell Motion turned on
7:37 PM Front Doorbell Motion turned off
7:34 PM Front Doorbell Motion turned on
6:56 PM Front Doorbell Motion turned off
6:53 PM Front Doorbell Motion turned on

Additional doorbot or motion dings seems just extend the time vs create new events. It was mostly this behavior that I was attempting to emulate, but now that I've worked out how to do it simply and flexibly, I'm less sure if that's how the API should behave, it's just how the Home Assistant Ring component behaves. I'll certainly leave this to your judgement.

@dgreif
Copy link
Owner

dgreif commented Jul 6, 2019

Thanks for the in-depth testing! Since the real ring api seems to follow a 60 second lifetime, I think I’ll stick with that. Good to know how home assistant handles it too.

@dgreif dgreif closed this as completed Jul 6, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants