Integrating Blue Iris, Pushover, Node-RED, and Amazon Rekognition

Hardly any. The heavy lifting are done by Blue Iris and Amazon, neither of which would be running on the same system as Home Assistant.

So Raspberry Pi is sufficient?

Yep, assuming you mean just Home Assistant. Blue Iris does the motion detection, HA submits the image to Amazon, Amazon does the image recognition, and Node-RED acts on the results. The load on HA and Node-RED is minimal, even running on a Pi.

Yes, just for Home Assistant. I have a Windows 10 machine for Blue Iris. I was concerned whether I needed a NUC (e.g. i3) for HA, or whether a Pi would suffice.

@TaperCrimp hey Taper or anyone else that has this working, I was wondering if you can help me figure out my issue with Rekognition service.
I posed in the original Rekognition thread however I wasn’t able to get help.

I am getting this error “An error occurred (UnrecognizedClientException) when calling the DetectLabels operation: The security token included in the request is invalid.”
So I am assuming that I have my credentials setup incorrectly but I am not sure what I am missing.

config looks like this

Image_processing:
  - platform: amazon_rekognition
    aws_access_key_id: AWS_ACCESS_KEY_ID
    aws_secret_access_key: AWS_SECRET_ACCESS_KEY
    target: Car # Optional target object, default Person
    source:
      - entity_id: camera.front_door

To get the aws id and secret I logged into aws and go to the IAM dashboard. Added a user and added them to a group that has the AmazonRekognitionFullAccess and AmazonRekognitionServiceRole policeies. Then in that user on the Security credentials I created an access key. I use that access key id for the AWS_ACCESS_KEY_ID and key that gets generated from that as the AWS_SECRET_ACCESS_KEY.

does anyone know if you can increase image quality with the snapshots ? I have 4k cameras but its compressed af atm. Excellent write up btw

I never played around with it. Mine just grabs a straight snapshot. It seems to pull it at 1280x720 even though the camera is set to 4K resolution.

@TaperCrimp is the node-red code flow available somewhere ? I would like to paste it into my node-red and customize it from there. Thanks!

This is a shortened version but should get you started.

[{"id":"c3f895bd.920f98","type":"server-state-changed","z":"4dc6f85c.c0d998","name":"Camera Motion","server":"744f1fa7.a5248","version":1,"entityidfilter":"binary_sensor.\\w{3}_motion","entityidfiltertype":"regex","outputinitially":true,"state_type":"str","haltifstate":"on","halt_if_type":"str","halt_if_compare":"is","outputs":2,"output_only_on_state_change":false,"x":300,"y":260,"wires":[["d9a8446b.14ace8"],[]]},{"id":"d9a8446b.14ace8","type":"change","z":"4dc6f85c.c0d998","name":"Convert","rules":[{"t":"delete","p":"payload","pt":"msg"},{"t":"set","p":"data.base_id","pt":"msg","to":"$match(topic, /binary_sensor.(\\w{3})_motion/).groups[0].$string()","tot":"jsonata"},{"t":"set","p":"data.camera","pt":"msg","to":"\"camera.\" & $.data.base_id","tot":"jsonata"},{"t":"set","p":"data.image_processing","pt":"msg","to":"\"image_processing.rekognition_person_\" & $.data.base_id","tot":"jsonata"},{"t":"set","p":"data.camera_snapshot","pt":"msg","to":"\"/config/www/camera_snapshot/snapshot_\" & $.data.base_id & \".jpg\"","tot":"jsonata"},{"t":"set","p":"payload.entity_id","pt":"msg","to":"\"image_processing.rekognition_person_\" & $.data.base_id","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":480,"y":260,"wires":[["436290dc.06661","1551375c.5c33f9"]]},{"id":"4ce9c8ae.253ef8","type":"api-current-state","z":"4dc6f85c.c0d998","name":"Person Check","server":"744f1fa7.a5248","version":1,"outputs":2,"halt_if":"0","halt_if_type":"num","halt_if_compare":"gt","override_topic":false,"entity_id":"","state_type":"num","state_location":"","override_payload":"none","entity_location":"aws_data","override_data":"msg","blockInputOverrides":false,"x":660,"y":380,"wires":[["e5338a5a.6f56d8"],[]]},{"id":"d20c1c8e.c9a9d","type":"api-call-service","z":"4dc6f85c.c0d998","name":"Rekognition","server":"744f1fa7.a5248","version":1,"service_domain":"image_processing","service":"scan","entityId":"","data":"{\"entity_id\":\"{{data.image_processing}}\"}","dataType":"json","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":790,"y":320,"wires":[["4ce9c8ae.253ef8"]]},{"id":"8333418b.c65ba","type":"comment","z":"4dc6f85c.c0d998","name":"Alert on people when everyone is away.","info":"","x":550,"y":220,"wires":[]},{"id":"adf5224b.68d5b","type":"api-call-service","z":"4dc6f85c.c0d998","name":"Snapshot","server":"744f1fa7.a5248","version":1,"service_domain":"camera","service":"snapshot","entityId":"{{data.camera}}","data":"{\"filename\":\"{{data.camera_snapshot}}\"}","dataType":"json","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":820,"y":260,"wires":[[]]},{"id":"436290dc.06661","type":"template","z":"4dc6f85c.c0d998","name":"Set Snapshot","field":"payload","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"{\n\t\"data\": {\n\t\t\"entity_id\": \"{{data.camera}}\",\n\t\t\"filename\": \"/config/www/camera_snapshot/snapshot_{{data.base_id}}.jpg\"\n\t}\n}","output":"json","x":660,"y":260,"wires":[["adf5224b.68d5b"]]},{"id":"1f004b53.fe4935","type":"pushover api","z":"4dc6f85c.c0d998","keys":"9f1dc855.c8bb68","title":"","name":"Alert","x":930,"y":440,"wires":[]},{"id":"4da2d34f.4fefdc","type":"function","z":"4dc6f85c.c0d998","name":"Payload","func":"msg.payload = \"Sensor: \" + msg.data.new_state.attributes.friendly_name + \"\\n\" + \"Person Confidence: \" + msg.person_confidence + \"%\";\nmsg.topic = \"Person Detected\";\nmsg.priority = 1;\nmsg.image = \"/config/www/camera_snapshot/snapshot_\" + msg.data.base_id + \".jpg\"\nreturn msg;","outputs":1,"noerr":0,"x":800,"y":440,"wires":[["1f004b53.fe4935"]]},{"id":"e5338a5a.6f56d8","type":"change","z":"4dc6f85c.c0d998","name":"Set Confidence","rules":[{"t":"set","p":"person_confidence","pt":"msg","to":"aws_data.attributes.Person","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":840,"y":380,"wires":[["19d17f21.4116d1"]]},{"id":"19d17f21.4116d1","type":"switch","z":"4dc6f85c.c0d998","name":"Confidence","property":"person_confidence","propertyType":"msg","rules":[{"t":"gte","v":"95","vt":"num"}],"checkall":"true","repair":false,"outputs":1,"x":650,"y":440,"wires":[["4da2d34f.4fefdc"]]},{"id":"1551375c.5c33f9","type":"delay","z":"4dc6f85c.c0d998","name":"Delay 1s","pauseType":"delay","timeout":"1","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":640,"y":320,"wires":[["d20c1c8e.c9a9d"]]},{"id":"744f1fa7.a5248","type":"server","z":"","name":"Home Assistant","legacy":false,"hassio":true,"rejectUnauthorizedCerts":true,"ha_boolean":"y|yes|true|on|home|open","connectionDelay":false},{"id":"9f1dc855.c8bb68","type":"pushover-keys","z":"","name":"Default API"}]

Great, thanks!

Anyone tried sending the payload through Pushbullet? I can’t seem too get the image payload too show. Root www directory is visible via the fqdn.

I’ll tell you how to send it through pushbullet if you tell me how you got the State node to work :wink:

In my PushBullet for the data I just have
{"message":"Some at the Door","data":{"file":"/config/www/camera_snapshot/snapshot.jpg"}}

I only have 1 camera that I am using the Rekognition with and I just overwrite the same image.

I need some help with the Person Check part.
I call image_processing part with the scan and my data is set tp
{"entity_id":"image_processing.rekognition_person_front_door"}

For the Person Check (edit current state node) If I leave the Entity ID blank I get an error saying that it is not allowed to be blank.
I have the Entity Location set to msg.aws_data

This is my flow


[{"id":"482bc774.91c718","type":"tab","label":"Front Door Motion","disabled":false,"info":""},{"id":"b332d5ac.adeb48","type":"api-call-service","z":"482bc774.91c718","name":"Fire Tablet Switch Tabs","server":"d277d7e0.b4f288","version":1,"service_domain":"browser_mod","service":"command","entityId":"","data":"{\"command\":\"navigate\",\"navigation_path\":\"/lovelace/3\",\"deviceID\":\"Fire Tablet\"}","dataType":"json","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":740,"y":500,"wires":[["16cf4955.d2ee37"]]},{"id":"37d82972.a5b056","type":"server-state-changed","z":"482bc774.91c718","name":"Front Door Motion","server":"d277d7e0.b4f288","version":1,"entityidfilter":"binary_sensor.front_door_motion","entityidfiltertype":"exact","outputinitially":false,"state_type":"str","haltifstate":"on","halt_if_type":"str","halt_if_compare":"is","outputs":2,"output_only_on_state_change":true,"x":130,"y":80,"wires":[["8c1bc3f0.6647","32c26666.b79c2a"],[]]},{"id":"8c1bc3f0.6647","type":"api-call-service","z":"482bc774.91c718","name":"SaveSnapShot","server":"d277d7e0.b4f288","version":1,"service_domain":"camera","service":"snapshot","entityId":"camera.front_door","data":"{\"filename\":\"/config/www/camera_snapshot/snapshot.jpg\"}","dataType":"json","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":460,"y":100,"wires":[[]]},{"id":"cbdc2f29.05623","type":"api-call-service","z":"482bc774.91c718","name":"Rekognition ","server":"d277d7e0.b4f288","version":1,"service_domain":"image_processing","service":"scan","entityId":"","data":"{\"entity_id\":\"image_processing.rekognition_person_front_door\"}","dataType":"json","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":370,"y":240,"wires":[["4f479071.d4803","b9ee335e.2ffb4"]]},{"id":"4f479071.d4803","type":"api-current-state","z":"482bc774.91c718","name":"Person Check","server":"d277d7e0.b4f288","version":1,"outputs":2,"halt_if":"0","halt_if_type":"num","halt_if_compare":"gt","override_topic":false,"entity_id":"image_processing.rekognition_person_front_door","state_type":"num","state_location":"","override_payload":"none","entity_location":"aws_data","override_data":"msg","blockInputOverrides":false,"x":480,"y":320,"wires":[["91363506.87e078","56cff9f7.97d5c8"],[]]},{"id":"91363506.87e078","type":"change","z":"482bc774.91c718","name":"Set Confidence","rules":[{"t":"set","p":"person_confidence","pt":"msg","to":"aws_data.attributes.Person","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":540,"y":380,"wires":[["169f3ef1.d94d01"]]},{"id":"169f3ef1.d94d01","type":"switch","z":"482bc774.91c718","name":"Confidence","property":"person_confidence","propertyType":"msg","rules":[{"t":"gte","v":"80","vt":"num"}],"checkall":"true","repair":false,"outputs":1,"x":630,"y":440,"wires":[["b332d5ac.adeb48","2d50ac3a.a30824"]]},{"id":"16cf4955.d2ee37","type":"delay","z":"482bc774.91c718","name":"","pauseType":"delay","timeout":"10","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":820,"y":560,"wires":[["94e990bd.ec4d"]]},{"id":"94e990bd.ec4d","type":"api-call-service","z":"482bc774.91c718","name":"Fire Back To Home","server":"d277d7e0.b4f288","version":1,"service_domain":"browser_mod","service":"command","entityId":"","data":"{\"command\":\"navigate\",\"navigation_path\":\"/lovelace/0\",\"deviceID\":\"Fire Tablet\"}","dataType":"json","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":910,"y":620,"wires":[[]]},{"id":"2d50ac3a.a30824","type":"api-call-service","z":"482bc774.91c718","name":"PushBullet","server":"d277d7e0.b4f288","version":1,"service_domain":"notify","service":"pb_notifier","entityId":"","data":"{\"message\":\"Some at the Door\",\"data\":{\"file\":\"/config/www/camera_snapshot/snapshot.jpg\"}}","dataType":"json","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":830,"y":440,"wires":[[]]},{"id":"32c26666.b79c2a","type":"delay","z":"482bc774.91c718","name":"","pauseType":"delay","timeout":"1","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":240,"y":160,"wires":[["cbdc2f29.05623"]]},{"id":"7583a78c.d67d38","type":"inject","z":"482bc774.91c718","name":"","topic":"","payload":"{\"entity_id\":\"binary_sensor.front_door_motion\"}","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":90,"y":240,"wires":[["cbdc2f29.05623"]]},{"id":"b9ee335e.2ffb4","type":"debug","z":"482bc774.91c718","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":870,"y":220,"wires":[]},{"id":"56cff9f7.97d5c8","type":"debug","z":"482bc774.91c718","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":900,"y":340,"wires":[]},{"id":"d277d7e0.b4f288","type":"server","z":"","name":"Home Assistant","legacy":false,"hassio":true,"rejectUnauthorizedCerts":true,"ha_boolean":"y|yes|true|on|home|open","connectionDelay":true}]

If someone could let me know what I am doing wrong that would be great.

I posted a simplified version of my flow a few comments up. It basically removed all of the “checks” I use before submitting the image, e.g. a person is home. I’d start with that and expand out from there.

Thanks, That fixed it.

Curious if anyone else has the same issue I have with this. Been running this for six months or so and it works great except for one small issue. When I restart Hassio a lot of the times 1 or more of the image_processing.rekognition entities (I have 3) show as unavailable. One or more restarts finally gets them all showing as available. Is there a way to delay the startup of the rekognition component at start up? Maybe that is the wrong way to try and fix this. It is not at all a deal breaker, just kind of annoying sometimes having to restart several times to get it up and going again.

I’ve had that happen before. It’s almost like it doesn’t register and it skips over it. Typically a restart of HASS fixes the issue. It’s been a long while since it happened though.

Hey guys, I was using this flow successfully for a while, but then disabled it until I get presence integrated to keep from getting notifications from indoor cameras when we were home.

Anyway, I was on HASSIO at the time, but I have since switched to separate docker containers on UNRAID.

Amazon Rekognition is working in HASS and the flow is working up to the Person Check node. Everytime the flow hits the Person Check node I get the following error:

TypeError: Joi.validate is not a function.

I do not see anything related in the HASS logs, but in the Node-Red logs I get a similar error message:

25 Oct 14:00:47 - [error] [api-current-state:Person Check] TypeError: Joi.validate is not a function

Here is a screenshot of my Person Check node:

Everything works as designed when the Person Check and Confidence nodes are bypassed. Obviously I get all motion images that way which is not ideal.

I’m not sure where to go from here and would appreciate some guidance.

That is a known issue in the custom component.

Hopefully @robmarkcole will be able to figure it out.

I figured out the problem. I had an outdated version of the home assistant websocket plugin. Once I upgraded the plugin and restarted Node-Red, it is working again.

I am not planning on doing any more work on the Rekognition CC, you could tryout https://github.com/robmarkcole/HASS-Google-Vision