Saving the latest Ring Door Bell video locally

Directly connect something to the camera? What do you suggest?
I solved it myself by using Macrodroid.

If I had any idea of how I would do it :smiley:
What do Macrodroid do?

I had the same problems using consumer grade wifi routers. I tried linksys velops (took them back after 2 days) then went with Netgear Orbi’s. After a year of shitty customer support, one terrible firmware release after another, I finally upgraded to Meraki MR-33’s and my 6 Floodlights and 2 doorbells cams are snappy and always producing quality audio/video for what they are. I had been blaming this on Ring for nearly a year, knowing my crappy Orbi RBR50’s sucked for other reasons, but turns out it was my crappy of the shelf wireless equipment. I will say one thing Ring customer support is top notch and have sent me free gear and replacement gear without question. I can’t talk them up enough. However now that I am experiment with facial recognition and object detection I am regretting it. Having to wait for a video to upload to the cloud to grab it and then analyze it and the latency with that sucks.

1 Like

I know this is a dumb question but I am new to this. After i install Python do i need a server to store/download my video’s? Also do i have to modify the script for my specific camera?

I am new to this and am lost. How can I set this up? pretend I am clueless :slight_smile: can you provide steps? with lots of details. I have the ring.com spot light wired

HERE’s A BIG FAT "BUMP"

So, I was just about to purchase a new Ring 2 for $99 bucks, but even now seeing technically and financially what you have to go through - I’m thinking that passing is the best thing?

That’s actually a question of opinion that I welcome hearing.

(Q) Because what I’m hearing… as a summary… Ring has made the script work around option obsolete by means of a firmware update? Is this right?

(Q) Since not currently owning a Ring 2 - can I ask if anyone knows what the latest firmware update is?

(Q) If anyone knows when the “fixed” firmware was implemented?

(Q) AND… if I were to acquire a Ring 2 that had a previous firmware - would I THEN be able to implement the script? Or… has Ring make the Ring 2 impossible to use without their cloud.

ON a side note…
I would think somehow… what Ring is doing would be illegal? In some sort of monopoly terms. Just because I buy a Ford, shouldn’t mean I can’t take it to a Honda repairman, right?

At least for now…
even at a good price…since not being able to get instant feedback - I think I’ll pass on the RING2. We already have outdoor NVR security camera system that sends notifications via email. What’s stupid??? Our insurance company will give us a discount for owning a crummy RING, but not the much more advance 8 camera system we have. Dumb, huh?!

1 Like

I was hoping there was a work around to store my video locally.
Instead of paying them 30 dollar per camera per year

Anyone know of a work around

Ok. So I was following along and I’m also a newbie. If i understand correctly, the ring doorbell video can be viewed thru Alexa or firestick on a TV. If that is true can a DVR be used to record what is being viewed on the TV? Anyone else have some onsite on this method? Thank you for any and all information.

Hi,
How do you use this script. Where does it live and how is it triggered?

Hi I’ve just made the same realisation others have since buying the over priced Ring or Ring 2 video doorbell and would not rather rely of a cloud based subscription but save video to a SD card or as this is not possible, to a local address on my home network, such as a QNAP NAS

does this work around still work or have the makers prevent it with recent updates?

if it does still work are there any instructions on how to do this?

1 Like

It’s certainly possible to download all of your videos, but it may require the subscription to do so (I’m not 100% sure as I have the subscription but some of the documentation I’ve seen implies that you do).

If you look at the camera.front_door (or whatever yours is called) there should be an attribute called video_url. That should contain a url to download the latest video. If you watch that URL and download it when it changes you should get all of the videos locally.

The ring.com component documentation isn’t 100% clear on how all of that works but it does work for me at least. I decided to try and implement the automation in Node Red (mainly as a project to teach myself Node Red). It’s not 100% perfect but it seems to work for me.

[
{
    "id": "2b6552b3.374a9e",
    "type": "server-state-changed",
    "z": "f368bccc.a1abc",
    "name": "",
    "server": "cd82d495.c5b69",
    "entityidfilter": "camera.front_door",
    "entityidfiltertype": "substring",
    "outputinitially": false,
    "haltifstate": "",
    "x": 154.5,
    "y": 388,
    "wires": [
        [
            "e7f892f5.a7"
        ]
    ]
},
{
    "id": "4e9cbec0.0e72f8",
    "type": "server-state-changed",
    "z": "f368bccc.a1abc",
    "name": "",
    "server": "cd82d495.c5b69",
    "entityidfilter": "camera.side_door",
    "entityidfiltertype": "substring",
    "outputinitially": false,
    "haltifstate": "",
    "x": 153,
    "y": 447,
    "wires": [
        [
            "e7f892f5.a7"
        ]
    ]
},
{
    "id": "70e044e4.50ba64",
    "type": "api-call-service",
    "z": "f368bccc.a1abc",
    "name": "",
    "server": "cd82d495.c5b69",
    "service_domain": "downloader",
    "service": "download_file",
    "data": "",
    "render_data": false,
    "mergecontext": "",
    "x": 945.5,
    "y": 572,
    "wires": [
        [
            "be7aa092.e462d8"
        ]
    ]
},
{
    "id": "5d66822d.4302a4",
    "type": "change",
    "z": "f368bccc.a1abc",
    "name": "",
    "rules": [
        {
            "t": "set",
            "p": "payload",
            "pt": "msg",
            "to": "{\t   \"data\":{\t       \"url\": data.new_state.attributes.video_url,\t       \"subdir\": topic,\t       \"filename\": $join([new.groups[0], \"_\", new.groups[1], \".mp4\"])\t   }\t}",
            "tot": "jsonata"
        },
        {
            "t": "delete",
            "p": "topic",
            "pt": "msg"
        },
        {
            "t": "delete",
            "p": "data",
            "pt": "msg"
        },
        {
            "t": "delete",
            "p": "new",
            "pt": "msg"
        },
        {
            "t": "delete",
            "p": "old",
            "pt": "msg"
        }
    ],
    "action": "",
    "property": "",
    "from": "",
    "to": "",
    "reg": false,
    "x": 677.5,
    "y": 576,
    "wires": [
        [
            "70e044e4.50ba64"
        ]
    ]
},
{
    "id": "be7aa092.e462d8",
    "type": "debug",
    "z": "f368bccc.a1abc",
    "name": "",
    "active": true,
    "tosidebar": true,
    "console": false,
    "tostatus": false,
    "complete": "true",
    "x": 1063,
    "y": 494,
    "wires": []
},
{
    "id": "4b7c8619.d2ec3",
    "type": "server-state-changed",
    "z": "f368bccc.a1abc",
    "name": "",
    "server": "cd82d495.c5b69",
    "entityidfilter": "camera.backyard",
    "entityidfiltertype": "substring",
    "outputinitially": false,
    "haltifstate": "",
    "x": 153,
    "y": 503,
    "wires": [
        [
            "e7f892f5.a7"
        ]
    ]
},
{
    "id": "ce6ed3ed.47d57",
    "type": "change",
    "z": "f368bccc.a1abc",
    "name": "",
    "rules": [
        {
            "t": "set",
            "p": "old",
            "pt": "msg",
            "to": "$match(data.old_state.attributes.video_url, /\\/(\\d+)\\/(\\d+)\\.mp4\\?/)",
            "tot": "jsonata"
        },
        {
            "t": "set",
            "p": "new",
            "pt": "msg",
            "to": "$match(data.new_state.attributes.video_url, /\\/(\\d+)\\/(\\d+)\\.mp4\\?/)",
            "tot": "jsonata"
        }
    ],
    "action": "",
    "property": "",
    "from": "",
    "to": "",
    "reg": false,
    "x": 716,
    "y": 752,
    "wires": [
        [
            "f36911e4.b5d1c"
        ]
    ]
},
{
    "id": "f36911e4.b5d1c",
    "type": "switch",
    "z": "f368bccc.a1abc",
    "name": "",
    "property": "(old.groups[0] = new.groups[0]) and (old.groups[1] = new.groups[1])",
    "propertyType": "jsonata",
    "rules": [
        {
            "t": "false"
        }
    ],
    "checkall": "true",
    "repair": false,
    "outputs": 1,
    "x": 569.5,
    "y": 510,
    "wires": [
        [
            "5d66822d.4302a4",
            "cd87ca57.0a22a8"
        ]
    ]
},
{
    "id": "cd87ca57.0a22a8",
    "type": "debug",
    "z": "f368bccc.a1abc",
    "name": "",
    "active": true,
    "tosidebar": true,
    "console": false,
    "tostatus": false,
    "complete": "true",
    "x": 775,
    "y": 491,
    "wires": []
},
{
    "id": "71446db9.0e1fb4",
    "type": "switch",
    "z": "f368bccc.a1abc",
    "name": "new video url is a string",
    "property": "data.new_state.attributes.video_url",
    "propertyType": "msg",
    "rules": [
        {
            "t": "istype",
            "v": "string",
            "vt": "string"
        },
        {
            "t": "else"
        }
    ],
    "checkall": "true",
    "repair": false,
    "outputs": 2,
    "x": 363.5,
    "y": 696,
    "wires": [
        [
            "ce6ed3ed.47d57"
        ],
        [
            "1d611991.cf2dce"
        ]
    ]
},
{
    "id": "e7f892f5.a7",
    "type": "switch",
    "z": "f368bccc.a1abc",
    "name": "old video url is a string",
    "property": "data.old_state.attributes.video_url",
    "propertyType": "msg",
    "rules": [
        {
            "t": "istype",
            "v": "string",
            "vt": "string"
        },
        {
            "t": "else"
        }
    ],
    "checkall": "true",
    "repair": false,
    "outputs": 2,
    "x": 349,
    "y": 573,
    "wires": [
        [
            "71446db9.0e1fb4"
        ],
        [
            "48764d51.11c0dc"
        ]
    ]
},
{
    "id": "48764d51.11c0dc",
    "type": "change",
    "z": "f368bccc.a1abc",
    "name": "set old url to a string",
    "rules": [
        {
            "t": "set",
            "p": "data.old_state.attributes.video_url",
            "pt": "msg",
            "to": "",
            "tot": "str"
        }
    ],
    "action": "",
    "property": "",
    "from": "",
    "to": "",
    "reg": false,
    "x": 145.5,
    "y": 642,
    "wires": [
        [
            "71446db9.0e1fb4"
        ]
    ]
},
{
    "id": "1d611991.cf2dce",
    "type": "change",
    "z": "f368bccc.a1abc",
    "name": "set new url to a string",
    "rules": [
        {
            "t": "set",
            "p": "data.new_state.attributes.video_url",
            "pt": "msg",
            "to": "",
            "tot": "str"
        }
    ],
    "action": "",
    "property": "",
    "from": "",
    "to": "",
    "reg": false,
    "x": 298,
    "y": 758,
    "wires": [
        [
            "ce6ed3ed.47d57"
        ]
    ]
},
{
    "id": "cd82d495.c5b69",
    "type": "server",
    "z": "",
    "name": "Home Assistant",
    "legacy": false,
    "hassio": false,
    "rejectUnauthorizedCerts": true
}
]

okay well, I’m in Australia and from what I’ve read we have a real lag problem as it has been suggested than servers in the US are used. I even notice that some ring alerts can take some time to reach my phone possibly for this very reason. I did ask a these questions of a consultant via [email protected] but as to servers got a don’t know answer and as to why cloud only, was told it was the most reliable. avoided the obvious answer of trying turning one time buyers into lifetime subscribers.

moreover who needs another paid subscription?!

All the above aside I don’t know coding but as I’m curious would be interested where and how this code is found.

Ultimately, I suspect I will simply buy one the many 1080p video doorbells which are now available on eBay with local storage and internal chime devices for a fraction of the Ring 2 RRP here

1 Like

The video_url attribute that I spoke about points to an Amazon S3 server. I don’t know what sort of presence Amazon has in Australia in terms of datacenters but that would certainly account for delays Australian users of ring.com doorbells see.

ring.com would certainly like you to get one :wink:

Which code? I doubt that you’ll ever see a legal copy of the code for the doorbell firmware or the server-side code either.

That’s the dilemma - DIY or buy. Personally I felt that going the DIY route for my video doorbell system probably would have resulted in a system that was perpetually 90% done and worked 75% of the time so I chose differently. Once things warm back up here in the states I’m going to get serious about installing some non-ring cameras to cover other areas of my property, so my security system will be at least partially DIY.

Is this script still working?

Yep, that’s why I got HASSIO and the Raspberry Pi. I was hoping to get around the security fee that Ring charges to download videos. If it were just an annual $30 fee, I’d pay for it, but it is $30/device. I have 3 devices, so that would be a $90 annual fee. And it looks like you can only get the “live view” from their app. The live view isn’t even available from their website. Their must be an API call from that app, and it probably passes credentials to initiate the live feed.

1 Like

Wow! Thank you. This was one of the very first things I tried to get working when I started with Home Assistant and was disappointed when I couldn’t get it working. I will now have a Ring Doorbell video archive! :slight_smile:

Now I just need to setup a routine to delete those videos after a week or two.

You aren’t paying the protect fee, but are able to add the ring camera to HA?

I am getting this error when I add the camera to my config:

Error: A Ring Protect Plan is required for the following cameras: Front Door.<br />You will need to restart hass after fixing.

Meant to reply to your comment ^^

Maybe I bought mine long enough ago that I am exempted somehow? I can show you some of my code.

Here are my Ring + Camera config settings.

ring:
  username: !secret email1
  password: !secret ring_pass

camera:
  - platform: ring

And I got the camera to display in a Lovelace view using:

  - type: picture-glance
    title: Porch
    entities:
      - binary_sensor.ring_porch_motion
      - binary_sensor.ring_porch_ding
    camera_image: camera.porch

And then I’m using jcollie’s Node-RED flow to store the files locally.

I am running Home Assistant in a Docker container instead of Hass.io, so I setup a command at 5am to delete all .mp4 files older than 14 days. I added the following command using ‘crontab -e’

0 5 * * * find “/opt/homeassistant/config/www/downloads/camera.porch” -maxdepth 1 -mtime +14 -type f -name ‘*.mp4’ -delete