dkilgore90 / google-sdm-api

Apache License 2.0
70 stars 22 forks source link

Add support for camera zones #81

Closed rjmcdougall closed 1 year ago

rjmcdougall commented 2 years ago

It would be nice if there was support for zones in each camera.

I thought there could be two ways to surface this -- either as an attribute on each camera, or implement a separate virtual camera device per zone. The latter is much easier to integrate into other workflows.

For example, I have a camera on the entire front yard and street. It picks up people as presence. I only want to trigger a motion event for people walking in the front yard, rather than the whole street.

For this I implemented a small change to the main app api so that it creates a second camera named "-zone 1" with a companion device-id with -zone1 appended.

From there, all hubitat rules etc can be applied and triggered on only zone1, so that you can do things like turn on lights etc.

Discovered devices are listed below:

[Entryway](https://10.0.2.40/device/edit/3066)
[Entryway-Zone1](https://10.0.2.40/device/edit/4033)
[Street](https://10.0.2.40/device/edit/3070)
[Street-Zone1](https://10.0.2.40/device/edit/4041)
[Max Room](https://10.0.2.40/device/edit/3071)
[Max Room-Zone1](https://10.0.2.40/device/edit/4043)
[Street High camera](https://10.0.2.40/device/edit/3140)
[Street High camera - Zone1](https://10.0.2.40/device/edit/4035)
[Driveway HD](https://10.0.2.40/device/edit/3069)
[Driveway HD-Zone1](https://10.0.2.40/device/edit/4039)
dkilgore90 commented 2 years ago

I can certainly see the appeal to this - so far I haven't seen anything in the API documentation (or in my own events) to suggest that the zones are exposed via the API. Do you have examples of events from the API (debug logs in Hubitat are fine) showing how events in different zones are represented? With that info I could develop a full solution

rjmcdougall commented 2 years ago

yes here it is

{ "sdm.devices.events.CameraPerson.Person": { "eventSessionId": "1646253940", "eventId": "806399652", "zones": ["Zone 1"] } } }
rjmcdougall commented 2 years ago

I have a prototype working

rjmcdougall commented 2 years ago

This is just a test-to-experiment:

Creating the device:

            if (device.type == "Camera") {
              // Zone 1
              device.id = it.name.tokenize('/')[-1] + "-Zone1"
              device.label = it.traits['sdm.devices.traits.Info'].customName ?: it.parentRelations[0].displayName + "-Zone1"
              log.warn('making zone 1 device: ' + device)
              def dev1 = makeRealDevice(device)
              if (dev1 != null) {
                  processTraits(dev1, it)
              }   

Redirecting the event:

def postEvents() {

…

    logDebug("dataJson: " + dataJson.resourceUpdate.events)
    def is_zone = false
    dataJson.resourceUpdate.events.each { key, value -> 
      logDebug("dataJson events key: " + key + " value: " + value)
      value.each { event_key, event_value -> 
        logDebug("dataJson event key: " + event_key + " value: " + event_value)
          if (event_key == "zones") {
              is_zone = true
          }
      }
    }
    logDebug("is_zone:" + is_zone)
    if (is_zone) {
      deviceId = deviceId + "-Zone1"
    }
    logDebug("device_id:" + deviceId)
rjmcdougall commented 2 years ago

I also now see on one camera - not sure why, but zones array has a key but no values:

"sdm.devices.events.CameraPerson.Person": { "eventSessionId": "1646254337", "eventId": "483713521", "zones": [""] }

dkilgore90 commented 2 years ago

I believe this occurs when a person is seen _outside_f of any defined zone.

I'm able to reproduce the zone tagging in events on my newer camera, will think on how best to create child devices (as different cameras may have different numbers of zones created) - and will likely generate HE event on both the primary device and the relevant zone child.

ScottyB007 commented 1 year ago

Hi, I've been looking everywhere for this functionality, has there been any progress? Is there anything I can do to help with testing?

dkilgore90 commented 1 year ago

@ScottyB007 thanks for the bump -- I had not worked on this for a while, but have pulled together some code for this -- currently soaking on my hub. If you're feeling adventurous, you can try this branch: https://github.com/dkilgore90/google-sdm-api/tree/zones -- note the new zoneChild driver (there are changes across the board in the App and all Drivers -- except thermostat).

Currently the child devices for each zone are created on-demand, so they will not exist until the first event is received referencing that zone. Obviously this isn't optimal, since folks will want to set up rules/triggers based on the zone devices -- I'm pondering the best way to pre-create them. Zone naming in the events is based on what users have named their zones in Google, so will need a way to map them.

ScottyB007 commented 1 year ago

Thank you for the very quick reply, I'll have a play with that branch this weekend.

ScottyB007 commented 1 year ago

@dkilgore90 thank you for updating the drivers, I implemented the app/drivers prior to the latest driver update and the zones were not getting created but it was working otherwise. Was thinking it was most likely something I missed on my end. I was just looking over it again now and noticed the drivers were updated 2 days ago. On updating the drivers, the zones are now getting created. I hope to get some time over the next couple of days to do some further testing but so far it looks great. Thank you for the fantastic work you have put into this.

ScottyB007 commented 1 year ago

@dkilgore90 Thank again for working on this, so far it's been working well. Cheers, Scott Baker