Introduction: Turn an Old Phone Into a Smart Doorbell Camera With Facial Recognition
CREDIT
This how to would not be possible if it weren't for Juan Perez & Robin Cole creating this article on Hackster.io. Please check it out.
Announce Who Is Home Using Facial Recognition
ASSUMPTIONS
Supplies
- IP Webcam - https://play.google.com/store/apps/details?id=com...
- MotionEye - https://github.com/ccrisan/motioneye/wiki
- Unraid - https://github.com/ccrisan/motioneye/wiki
- Docker - https://github.com/ccrisan/motioneye/wiki
- Facebox - https://github.com/ccrisan/motioneye/wiki
- Home Assistant - https://github.com/ccrisan/motioneye/wiki
- Discord - https://github.com/ccrisan/motioneye/wiki
- Google home devices
Step 1: Getting Home Assistant Ready for MotionEye
Add two input_booleans to your Home Assistance configuration.yaml file.
front_door_motion_sensor gives us a way to turn a switch off and on using MotionEye
front_door_motion_sensor_face_detect_this_pass We will use this later when we are making automations
configuration.yaml
input_boolean: front_door_motion_sensor: initial: off front_door_motion_sensor_face_detect_this_pass: initial: off
Below that we can add a binary sensor that ties directely to input boolean we just made.
front_door_motion_sensor gets it value directly from the input_boolean with the same name
configuration.yamlbinary_sensor: - platform: template sensors: front_door_motion_sensor: entity_id: input_boolean.front_door_motion_sensor device_class: motion value_template: '{{ is_state("input_boolean.front_door_motion_sensor", "on") }}'
Step 2: Create Long Live Token to Use With MotionEye
- In Home assistant click on the user profile name
- Scroll all the way down
- Click Create Token
- Name the token
- Save the token for later
Step 3: Install IP Webcam on Your Phone
- Install IP Webcam from the app store
- Start the app
- Click start server
- Save the URL provided from the app
*You will need to assign your phone a static IP so that the URL doesn't change
Step 4: Connect Your Phone to Motioneye
- Click the hamburger on the left
- Click the drop down
- Click add camera...
- choose Camera Type - Network Camera
- Type the URL from the IP Webcam app and add "/video" to the end
- Example: http://192.168.1.121:8080/video
- Click inside the camera input
- An MJPEG Network Camera should appear
- Click OK
The camera from your phone should now be connected to MotionEye.
Step 5: Configuring MotionEye Camera Settings
- Scroll down to Video Streaming
- Make sure Video Streaming is ON
- Scroll down to Motion Detection
- Make sure Motion Detection is turned ON
- You will have to adjust the settings in the area to make sure your MotionEye isn't detecting motion too much or too little
- Scroll Down to Motion Notifications
- Turn on Run A Command
- Edited the following string and paste it into the Run A Command
- You will need your Home Assistant Long Lived Access Token that you made earlier
- You will need your Home Assistant IP address and port
curl -X POST -k -H "Authorization: Bearer [YOUR TOKEN GOES HERE]" -H "Content-Type: application/json" -d '{"entity_id": "input_boolean.front_door_motion_sensor"}' http://[YOUR HOME ASSISTANT IP ADDRESS AND PORT]/api/services/homeassistant/turn_on
8. Turn on Run An End Command
9. Edited the following string and paste it into the Run A Command
curl -X POST -k -H "Authorization: Bearer [YOUR TOKEN GOES HERE]" -H "Content-Type: application/json" -d '{"entity_id": "input_boolean.front_door_motion_sensor"}' http://[YOUR HOME ASSISTANT IP ADDRESS AND PORT]/api/services/homeassistant/turn_off
Now when Motion is detected you should see it reflected on the Home Assistant entity binary_sensor.front_door_motion_sensor.
Step 6: Integrate Facebox With Home Assistant
Choose a file location to download a still image of the front door I chose '/surveillance/front_door/'
You will also need the URL to retrieve this still image. You can find this on your MotionEye web page --> Video Streaming --> Snapshot URL
configuration.yaml
shell_command: download_front_door_image: cd /surveillance/front_door/ && wget http://[YOUR MOTIONEYE IP]:[YOUR MOTIONEYE PORT]/picture/1/current/ && mv index.html front_door.jpg
Add two cameras to your Home Assistant's configuration.yaml file
configuration.yaml
camera: - platform: local_file name: front_door_local_file file_path: /surveillance/front_door/front_door.jpg - platform: generic name: front_door still_image_url: http://[YOUR MOTIONEYE IP]:[YOUR MOTIONEYE PORT]/picture/1/current/ ### MotionEye --> Video Streaming --> Snapshot URL
Add the Facebox image processing information to your Home Assistant's configuration.yaml file.
configuration.yaml
image_processing: - platform: facebox ip_address: [YOUR FACEBOX IP] port: [YOUR FACEBOX PORT] scan_interval: 10000 source: - entity_id: camera.front_door name: facebox_front_door
Step 7: Teaching Facebox
The free version of Facebox lets you train 100 faces but does not retain what it learned after a reboot. To circumvent this issue we need to check on a regular bases that the faces are taught.
- Download this python script - github
- From your Home Assistant's appdata folder create a folder named facebox
- Change directory into the facebox folder and create a folder named teach
- Place the teach_facebox.py script into the teach folder
- Open the teach_facebox.py scipt in an editor
- Change line 9 to match the IP of your Facebox instance
- Change line 10 to match the port of your Facebox instance
- In the teach folder create folders that are named after the person who's face you want to teach to Facebox
- In the personnel folders place photos of those people
We need to add a shell command in Home Assistant so that it can automatically call it when faces are not taught. Add the teach_facebox command under the download_front_door_image command
configuration.yaml under shell_command:
teach_facebox: cd /config/facebox/teach && python /config/facebox/teach/teach.py
We need to create a binary_sensor that checks to make sure a face is taught. This sensor will run every 5 minutes. To do this we are going to need a random face to test off of. In the teach folder I created another folder called xyz. I got a random face off of This Person Does Not Exist and put that picture in the xyz folder.
- In the teach folder create another folder called xyz
- Download a picture of a random face from https://thispersondoesnotexist.com/
- Put that picture in the xyz folder
configuration.yaml under binary_sensor:
- platform: command_line name: facebox_taught command: curl -X POST -F 'file=@/config/facebox/teach/xyz/xyz.png' http://[YOUR FACEBOX IP]:[YOUR FACEBOX PORT]/facebox/check | tac | head -14 | grep -i "name" | awk 'FNR==1 {print $2}' | sed 's/"//g' | sed 's/,//g' device_class: connectivity scan_interval: 5 payload_on: "yes" payload_off: "no" value_template: '{%- if value == "xyz" -%} yes {%- else -%} no {%- endif -%}'
Now for our first automation. We need to teach Facebox if the xyz face is not recognized.
automations.yaml
- id: teach_facebox alias: 'teach facebox' initial_state: on trigger: - platform: time_pattern minutes: '/1' condition: - condition: state entity_id: binary_sensor.facebox_taught state: 'off' action: - delay: 00:00:05 - service: shell_command.teach_facebox
Step 8: Automation - While Motion at Front Door Scan for Faces
Trigger - When motion is detected at the front door
Condition - No faces have been detected this pass
Action - Run a command to download an image of the front door and send the image to Facebox to scan
automations.yaml
- id: 'while_motion_at_front_door_scan_for_faces' alias: while motion at front door scan for faces trigger: - entity_id: binary_sensor.front_door_motion_sensor from: 'off' platform: state to: 'on' - platform: time_pattern seconds: '/1' condition: - condition: state entity_id: binary_sensor.front_door_motion_sensor state: 'on' - condition: state entity_id: input_boolean.front_door_motion_sensor_face_detect_this_pass state: 'off' action: - service: shell_command.download_front_door_image - entity_id: image_processing.facebox_front_door service: image_processing.scan
Step 9: Automation - Faces Detected at Front Door
Trigger - When Facebox detects faces in an image of the front door
Condition - Faces have not been detected this pass
Action - Turn on the input boolean front_door_motion_sensor_face_detect_this_pass
automations.yaml
- id: 'faces_detected_at_front_door' alias: faces detected at front door trigger: - event_type: image_processing.detect_face platform: event event_data: entity_id: image_processing.facebox_front_door condition: - condition: state entity_id: input_boolean.front_door_motion_sensor_face_detect_this_pass state: 'off' action: - service: input_boolean.turn_on data: entity_id: input_boolean.front_door_motion_sensor_face_detect_this_pass
Step 10: Automation - Cast Front Door to Living Room Tv If Face Detected
Trigger - When faces have been detected this pass
Condition - The TV is not currently casting anything
Action - Stream the front door camera to the TV then wait till motion is no longer detected and the front door and then turn off the stream
automations.yaml
- id: 'cast_front_door_to_living_room_tv_if_face_detected' alias: "cast front door to living room tv if face detected" trigger: - entity_id: input_boolean.front_door_motion_sensor_face_detect_this_pass from: 'off' platform: state to: 'on' condition: condition: state entity_id: media_player.living_room_tv state: 'off' action: - service: media_player.play_media data_template: entity_id: - media_player.living_room_tv media_content_id: http://[YOUR MOTIONEYE IP]:[YOUR CAMERA PORT] media_content_type: image/jpg - wait_template: '{{ is_state(''binary_sensor.front_door_motion_sensor'', ''off'') }}' - service: media_player.turn_off entity_id: media_player.living_room_tv
Step 11: Automation - Cast TTS Front Door to Speakers If Face Detected
Trigger - When faces have been detected this pass
Condition - Nothing is currently playing on the dining room speaker
Action - Set the volume to 50% then announce the names of the people whom faces were detected at the front door
- id: 'cast_TTS_front_door_to_speakers_if_face_detected' alias: "cast TTS front door to speakers if face detected" trigger: - entity_id: input_boolean.front_door_motion_sensor_face_detect_this_pass from: 'off' platform: state to: 'on' condition: condition: or conditions: - condition: state entity_id: media_player.dining_room_speaker state: 'off' - condition: state entity_id: media_player.dining_room_speaker state: 'idle' action: - service: media_player.volume_set data: entity_id: - media_player.dining_room_speaker volume_level: .5 - service_template: tts.google_translate_say data_template: entity_id: > {% if not is_state('media_player.dining_room_speaker', 'playing') and not is_state('media_player.office_speaker', 'playing') %} media_player.dining_room_speaker, media_player.office_speaker {% elif not is_state('media_player.dining_room_speaker', 'playing') %} media_player.dining_room_speaker {% elif not is_state('media_player.office_speaker', 'playing') %} media_player.office_speaker {% endif %} message: 'At the front door: {% for face in states.image_processing.facebox_front_door.attributes.faces -%} {% if not face.name == None %} {{ face.name }} {% if not loop.last %}, {% endif -%} {% endif -%} {%- endfor %} {% if states.image_processing.facebox_front_door.attributes.total_faces > states.image_processing.facebox_front_door.attributes.total_matched_faces %} + {{ states.image_processing.facebox_front_door.attributes.total_faces - states.image_processing.facebox_front_door.attributes.total_matched_faces }} unrecognised person(s) {% endif -%}'
Step 12: Automation - Front Door Discord Notification If Face Detected
Make sure you've integrated your discord and home assistant. HOW TO
Trigger - When faces have been detected this pass
Action Send a discord notification with a photo of the people whom faces were detected at the front door
- id: 'front_door_discord_notification_if_face_detected' alias: "front door discord notification if face detected" trigger: - entity_id: input_boolean.front_door_motion_sensor_face_detect_this_pass from: 'off' platform: state to: 'on' action: - service_template: notify.discord data_template: data: images: - /surveillance/front_door/front_door.jpg message: ' At the front door: {% for face in states.image_processing.facebox_front_door.attributes.faces -%} {% if not face.name == None %} {{ face.name }} {% if not loop.last %}, {% endif -%} {% endif -%} {%- endfor %} {% if states.image_processing.facebox_front_door.attributes.total_faces > states.image_processing.facebox_front_door.attributes.total_matched_faces %} + {{ states.image_processing.facebox_front_door.attributes.total_faces - states.image_processing.facebox_front_door.attributes.total_matched_faces }} unrecognised person(s) {% endif -%}' target: - '[YOUR DISCORD CHANNEL ID]'
Step 13: Automation - Turn Off Front Door Face Detected This Pass
This is a very important automation to wrap everything up. Without it you will have some problems with people being announced that aren't actually there.
Trigger - When motion at the front door has stopped
Action - Set the input boolean value for front_door_motion_sensor_face_detect_this_pass to off and reset the while_motion_at_front_door_scan_for_faces automation
- id: 'turn_off_front_door_face_detected_this_pass' alias: turn off front door face detected this pass trigger: - entity_id: binary_sensor.front_door_motion_sensor from: 'on' platform: state to: 'off' action: - service: input_boolean.turn_off data: entity_id: input_boolean.front_door_motion_sensor_face_detect_this_pass - service: automation.turn_off data: entity_id: automation.while_motion_at_front_door_scan_for_faces - service: automation.turn_on data: entity_id: automation.while_motion_at_front_door_scan_for_faces