ratgdo / homekit-ratgdo

A native HomeKit implementation of a Security+ 2.0 garage door controller based on ratgdo hardware
https://ratgdo.github.io/homekit-ratgdo/
GNU General Public License v3.0
214 stars 21 forks source link

Add Homekit Sensor for Obstruction similar to Motion #219

Closed nchansen closed 3 months ago

nchansen commented 3 months ago

Looking at the HomeKit code it appears it has all of the framework for handling obstruction status other than registering the obstruction sensor to homekit. I would like to setup an automation based on obstruction.

donavanbecker commented 3 months ago

Obstruction sensors in HomeKit don't have a way to be used with automation. You would have to be able to add the obstruction sensors as a contact sensor or motion sensor. Which I don't think anyone would want to add as this project is designed to be native HomeKit firmware, without hacks.

nchansen commented 3 months ago

Why not motion, technically the obstruction sensor detects when a car or person moves between the beam?

dkerr64 commented 3 months ago

We already have a motion sensor. Yes it is different motion, but I bring it up because if we add a motion sensor accessory to represent obstruction then we now have two HomeKit accessories of the same type. And that creates complications.

While it might work just fine, the HomeKit spec requires special coding when there are multiple accessories of the same type... in order to identify between them. We need to additionally add a ServiceLabel accessory and a ServiceLabelIndex characteristic to each of the accessories. The typical use case for this is a power strip with multiple electrical outlets, as in this example here.

Now it is not impossible, but it is additional burden which makes implementing this request non-trivial.

PaulWieland commented 3 months ago

You could have just one HK Motion sensor that is triggered by several different events. The sec+2 motion sensor if present, the obstruction beam, the wall button press and the light turning on. Any/all of those indicate motion in the garage.

In the ESP Home firmware, the motion event is also triggered when the light turns on (as this is what happens when you break the obstruction beam or when a security + 1 motion panel detects motion).

dkerr64 commented 3 months ago

I like Paul's idea. If we do anything keep the one motion sensor accessory and trigger it from any GDO event that implies motion. Which, for extra credit, we could make optional through a setting.

nchansen commented 3 months ago

Due to the complexity I do like having a single motion sensor in HomeKit with a setting that can dictate how it is used (motion,  obstruction, or bothSent from my iPhoneOn Jul 31, 2024, at 5:24 PM, David Kerr @.***> wrote: I like Paul's idea. If we do anything keep the one motion sensor accessory and trigger it from any GDO event that implies motion. Which, for extra credit, we could make optional through a setting.

—Reply to this email directly, view it on GitHub, or unsubscribe.You are receiving this because you authored the thread.Message ID: @.***>

jgstroud commented 3 months ago

You can create automations triggered by the obstruction sensor in the Eve app

nchansen commented 3 months ago

Hmm, I have the Eve App and it does not show the obstruction sensor at all. I am using the latest HomeKit build.

donavanbecker commented 3 months ago

It will show if you create an automation:

image

dkerr64 commented 3 months ago

@jgstroud it appears that there is no handling of obstruction at all in our code. comms.cpp does not handle it at all for sec+ 2.0, there is scaffolding for it in sec+ 1.0 but nothing is done with it.

However, Packet.h does have code for it. But my logs are always showing obstruction as true...

>>> [ 104193] RATGDO: reader completed packet
>>> [ 104193] RATGDO: DECODED  0001CF90 000000C0BC1A200A 40609281
>>> [ 104194] RATGDO: PACKET(0x1A200A @ 0x1CF90) Status - Status: [DoorState Closed, Parity 0x9, Obs 1, Lock 0, Light 0]
>>> [ 104203] RATGDO: tgt 1 curr 1

I have not yet tried to cause an obstruction, but thought it odd that it was always true (unless true means no obstruction!)

jgstroud commented 3 months ago

@dkerr64 We do handle obstructions but it's a separate digital input handled by an interrupt handler. I think there are also sec+2 messages, but you are right that we don't handle those. Obstructions definitely do work, as I have tested them many times. The last release I merged a change that was supposed to improve the obstruction handling by filtering out some false obstructions. For instance, when my lights would turn on, it would cause a momentary blip on the sensor and that should now be filtered out. The handler is all in ratgdo.cpp.

dkerr64 commented 3 months ago

Humm... something is working...

>>> [1398494] RATGDO: reader completed packet
>>> [1398498] RATGDO: DECODED  0001CF97 000000C0BC1A200A 4260B281
>>> [1398502] RATGDO: PACKET(0x1A200A @ 0x1CF97) Status - Status: [DoorState Closed, Parity 0xB, Obs 1, Lock 0, Light 1]
>>> [1398509] RATGDO: tgt 1 curr 1
>>> [1403096] RATGDO: reader completed packet
>>> [1403105] RATGDO: DECODED  00002DD6 000000D24C521910 0000F085
>>> [1403110] RATGDO: PACKET(0x521910 @ 0x2DD6) Motion - NoData: [Zero: 0x00000000, Parity: 0xF]
>>> [1403114] RATGDO: Motion Detected
>>> [1403120] RATGDO: ENCODING 0000030B 000000000091A539 00000080
>>> [1403251] RATGDO: reader completed packet
>>> [1403372] RATGDO: DECODED  0001CF97 000000C0BC1A200A 4260B281
>>> [1403377] RATGDO: PACKET(0x1A200A @ 0x1CF97) Status - Status: [DoorState Closed, Parity 0xB, Obs 1, Lock 0, Light 1]
>>> [1403381] RATGDO: tgt 1 curr 1
>>> [1407624] RATGDO: Obstruction Detected
>>> [1407629] HomeKit: [Client 1073699812] Got characteristic 1.13 change event True
>>> [1407634] RATGDO: SSE send to client 192.168.17.5 on channel 0, data: { "garageObstructed": true, "upTime": 1407633 }
>>> [1407645] RATGDO: SSE send to client 192.168.17.5 on channel 1, data: { "garageObstructed": true, "upTime": 1407633 }
>>> [1407778] RATGDO: Obstruction Clear
>>> [1407782] HomeKit: [Client 1073699812] Got characteristic 1.13 change event False
>>> [1407786] RATGDO: SSE send to client 192.168.17.5 on channel 0, data: { "garageObstructed": false, "upTime": 1407785 }
>>> [1407795] RATGDO: SSE send to client 192.168.17.5 on channel 1, data: { "garageObstructed": false, "upTime": 1407785 }
>>> [1408119] RATGDO: Motion Cleared
>>> [1408125] RATGDO: SSE send to client 192.168.17.5 on channel 0, data: { "garageMotion": false, "upTime": 1408124 }
>>> [1408136] RATGDO: SSE send to client 192.168.17.5 on channel 1, data: { "garageMotion": false, "upTime": 1408124 }
>>> [1424340] RATGDO: Obstruction Detected
>>> [1424348] HomeKit: [Client 1073699812] Got characteristic 1.13 change event True
>>> [1424353] RATGDO: SSE send to client 192.168.17.5 on channel 0, data: { "garageObstructed": true, "upTime": 1424352 }
>>> [1424363] RATGDO: SSE send to client 192.168.17.5 on channel 1, data: { "garageObstructed": true, "upTime": 1424352 }
>>> [1424565] RATGDO: reader completed packet
>>> [1424569] RATGDO: DECODED  0001CF97 000000C0BC1A200A 0000C084
>>> [1424573] RATGDO: PACKET(0x1A200A @ 0x1CF97) Obst1 - NoData: [Zero: 0x00000000, Parity: 0xC]
>>> [1424577] RATGDO: Support for Obst1 packet unimplemented. Ignoring.
>>> [1424645] RATGDO: reader completed packet
>>> [1424659] RATGDO: DECODED  0001CF97 000000C0BC1A200A 0000D085
>>> [1424664] RATGDO: PACKET(0x1A200A @ 0x1CF97) Obst2 - NoData: [Zero: 0x00000000, Parity: 0xD]
>>> [1424667] RATGDO: Support for Obst2 packet unimplemented. Ignoring.
>>> [1424731] RATGDO: reader completed packet
>>> [1424735] RATGDO: DECODED  0001CF98 000000C0BC1A200A 4660F281
>>> [1424739] RATGDO: PACKET(0x1A200A @ 0x1CF98) Status - Status: [DoorState Closed, Parity 0xF, Obs 1, Lock 0, Light 1]
>>> [1424745] RATGDO: tgt 1 curr 1
>>> [1424977] RATGDO: Obstruction Clear
>>> [1424981] HomeKit: [Client 1073699812] Got characteristic 1.13 change event False
>>> [1424985] RATGDO: SSE send to client 192.168.17.5 on channel 0, data: { "garageObstructed": false, "upTime": 1424984 }
>>> [1424994] RATGDO: SSE send to client 192.168.17.5 on channel 1, data: { "garageObstructed": false, "upTime": 1424984 }
>>> [1426678] RATGDO: reader completed packet
>>> [1426682] RATGDO: DECODED  0001CF98 000000C0BC1A200A 0000C084
>>> [1426686] RATGDO: PACKET(0x1A200A @ 0x1CF98) Obst1 - NoData: [Zero: 0x00000000, Parity: 0xC]
>>> [1426690] RATGDO: Support for Obst1 packet unimplemented. Ignoring.
>>> [1426757] RATGDO: reader completed packet
>>> [1426764] RATGDO: DECODED  0001CF98 000000C0BC1A200A 0000D085
>>> [1426769] RATGDO: PACKET(0x1A200A @ 0x1CF98) Obst2 - NoData: [Zero: 0x00000000, Parity: 0xD]
>>> [1426773] RATGDO: Support for Obst2 packet unimplemented. Ignoring.
>>> [1426832] RATGDO: reader completed packet
dkerr64 commented 3 months ago

okay, so it looks like obstruction is handled within ratgdo.cpp... different from open/close/light/lock/motion. Strange, I wonder how that happened.

But it would be possible therefore to tell HomeKit that motion was detected when obstruction is detected. I notice that the motion code has a 5 second timeout (turns motion off after 5 seconds). Do we need that here? I think not because from above log the obstruction clears pretty quickly.

dkerr64 commented 3 months ago

So... we could add a user interface setting to trigger motion on obstruction. If that setting is enabled then we would always enable_service_homekit_motion() rather than only do that on first motion (code added to support doors without a motion detector). Then in ratgdo.cpp we would set the door motion to mirror that of obstruction and call notify_homekit_motion()

I think that would work, no need for the 5 second time out as that is specific to the motion detector.

jgstroud commented 3 months ago

okay, so it looks like obstruction is handled within ratgdo.cpp... different from open/close/light/lock/motion. Strange, I wonder how that happened.

Because the obstruction sensors signals are monitored directly. That's why those need to be wired directly in to the ratgdo. This code is a direct copy from both the mqtt and esphome firmware. I think this is the most reliable way of detecting obstructions.

dkerr64 commented 3 months ago

@jgstroud yes, I think it is fairly easy to set/reset of motion sensor in the code that handles obstruction.

Now @PaulWieland suggests triggering motion when the wall panel is pressed. I'm wondering if it is possible to detect that... Pressing door open/close, light or lock buttons at the panel would indicate a human presence. But I would not want to trigger motion if any of those activities were set by HomeKit, the OEM app, or the ratgdo web page, as that can be done remotely. I've not looked at this yet, but anyone know?

Thanks

dkerr64 commented 3 months ago

I have implemented triggering motion sensor on obstruction and have it in PR #220 ready for next time we do a merge and release.

I coded it such that we could easily add triggering on wall panel key presses (light/lock/door) if we are able to do that... at lease the settings part is easily added!

dkerr64 commented 3 months ago

I have added option to trigger motion sensor when light is turned on/off at the wall panel. I can test on Sec+ 2.0 but need someone to test on Sec+ 1.0. I may push a pre-release to seek testing of that.

jgstroud commented 3 months ago

You could just make it trigger on any door movement.

dkerr64 commented 3 months ago

implemented in v1.7