[APP][Pro] Ring Security System (in development)

Install the app

There is no public version to test yet!

What does this app get you?

This app connects to the Ring API and reads your location armed state on an interval. Whenever the current state changes to another, the change will be fired as an event that can be used to trigger flows with.

For now I have no other intentions with this app than added armed state flow cards. But feel free to think out loud… who knows what can be added.


Features

  • Trigger automation when alarm state changes to none (off)
  • Trigger automation when alarm state changes to all (armed)
  • Trigger automation when alarm state changes to some (home)

Source code

Current version is in the staging branch.

Roadmap

Changelog

So, let me kick this off with what I’m working on. Today I installed my Ring alarm and was eager to get this thing connected to Homey and automate flows based of the new / current state of the alarm.

As I had purchased the alarm system about a year and a half ago, I hadn’t been able to check it’s compatibility with Homey before. Unfortunately for me, the Ring Alarm isn’t supported yet and the available app (Ring Security) only allows you to make use of its components and doesn’t connect to the actual Ring system itself.

For now, I have no idea what this will result in. But I’ve got a few simple things working that at least makes me think I’m up to something.

Automate your home based on the alarm state?

So, what I want to do is read the state of my alarm at home and create flows based on the current state or based on a change of it’s state. I specifically say “read”, because I have no intention in adding functionality to this app that is able to arm the alarm. As far as I’m concerned the Ring system handles this well enough and there’s no reason for me to add a possible backdoor in my alarm system that can be exposed via this app. So: all I want to know from the system is what it’s current state is - read only!

The Ring alarm knows 3 states:

  1. none: which means nothing is armed (“off”)
  2. some: which means some parts are armed (“home”)
  3. all: everything is armed (“on” - possible bypassed sensors)

I want these states to be available in flows to either have flows start when the state changes to X or continue flows if the state is equal to X. Or variants like is not equal to home or equals on or home etc.

What have I tested so far?

  1. The example screenshot in the first post was set up as a simple proof-of-concept. It uses a RingArmed boolean which is being watched by a flow. As soon as the boolean changes it executes the flow and turns a light in my home green or red based on the state. This is possibly the simplest implementation of what I’m after.
  2. Using the ring-client-api, which is an unofficial API sdk to the Ring system, I connected to the Ring API and was able to read all my locations (currently a single one) and get the armed state of my home.
  3. Using a simple interval I got the state to update every 15 seconds.

What are my next steps

  1. Create a trigger flow card When the alarm state changes to armed and get the example screenshot working based on the actual reading of the alarm state.
  2. If that works add more flow cards (only “when” and “and” cards for the state of the alarm!)
  3. Add a device driver for Ring Locations - the Location is the entity in the API that holds the armed state of your home. As Ring supports multiple Locations it would be nice to have the options to connect multiple locations and even combine system states if that’s what you’re after.
  4. Figure out how to get the auth system working: it requires a one-time login using your Ring account username and password and possibly your 2FA token. An auth (refresh) token is then saved and refreshed as long as the app is running.

Especially that last part is something I could use some help with. Afaik, I can’t do this using the homey-oauth2 package because I have no knowledge about the Ring OAuth client. But who knows what secrets the unofficial API repo holds for us to use.

3 Likes

Good news! I’ve just got the proof of concept version working with the flow below:

Basically how this works:

This current version can be found at Github in the staging branch.

  1. Clone the repo and npm i the dependencies
  2. Create a refreshToken via npx -p ring-client-api ring-auth-cli command
  3. Set the refreshToken in env.json
  4. Set the location id in env.json, which can be found via ringApi.getLocations(). For this moment you’d have to dump the results of locations yourself to find a valid id.
  5. Run the app using homey app run

At this point the app is running for just a single location. The app takes care of requesting the state of your location every 10 seconds and in case the state changes it saves the new current state and triggers the “Ring arm state changed” card (“when” action). This is the first card in the example above. The card has a token called armed-state which can be used as parameter in the cards you connect to it, which can be seen in the second card.

Whats next?

  1. :white_check_mark: I’m getting a (generic?) error after a few reads saying throw Error("invalid wire type " + wireType + " at offset " + this.pos);. I’m not sure where this one comes from but after 60 seconds it crashes the app. It goes without saying that this needs to be fixed first.
  2. Next I have to convert the setup for the Ring API into a driver which takes care of logging in and getting + updating the correct refresh token which is used to keep the connection between Homey and the Ring API alive.
  3. After that, I need to add Ring Locations as devices to the app. This way you can, for example, listen to state changes for location “Home” and/or location “Office”. So the trigger card will be scoped to a given location.

As my knowledge on typescript and Homey is limited I’m curious to see how fast I’ll get step 2 up and running. That’s the one step I look up to doing,… :man_shrugging: I’d gladly accept any help!

So, the error that made the app crash is fixed. Well… fixed… after rebooting Docker and installed the app to Homey it simply stopped occurring. I guess it wasn’t anything in the app after all.

I have the app running for a little under 24h now without crashes and so far it does what I expect it to do. Below is an example I’m currently testing the app with, I think most of you understand what the use case will be but this is a better real life example of what I’m going to use it for:

For this test I’m just listening to the “some” state (which is partially armed) and not the “all” state (fully armed) to prevent the alarm from going mental while testing :slight_smile:

Just a little update this time:

While the error that was (probably) caused by Docker hasn’t come back. There is an issue somewhere that makes the app crash. When I have it running for a full day I noticed my notification center to have a recurring amount of “The alarm state changed to none” events. Which means the app crashed, restarted and sensed the initial status (none) again.

I don’t think this is a hard one to crack, but I find it hard getting useful debug information due to the lack of log files? I guess I need to ssh into Homey and find out myself.

Besides that, there’s another thing that bothers me. The ring-client-api npm package turns out to be 120 MB. Which is an awful lot for what this app can do. There are a lot of dependencies that get downloaded aswel (Homebridge code, ffmpeg, etc.). Looking at what space my Homey currently uses I don’t think it’s a problem for my scenario. But compared to my Spotify app, which (in code) does more that this one, that’s a huge difference: 120MB vs 1.3MB. I’m not sure what to do about this one, because the ring-client-api package does all the heavy lifting for the Ring API side and stripping this from their package only causes more maintenance work on this app for me in case anything changes at Ring.

So far not further updates. I’m going to try and fix the crashing app this weekend and see if I can make a start for the UI to connect your Ring account to the app.