Open joeyberkovitz opened 6 years ago
I'm not sure what I can do, I don't have the Ring alarm to test with. Hopefully someone else watching this repo can chime in.
Thanks anyway. Figured out that the correct websocket URL is actually "wss://" + alarmConnection.server + "/?authcode=" + alarmConnection.authCode, which enabled me to establish a connection.
Will provide updates as I build out a client.
Definitely watching this thread, I just got the alarm and would love to tie it in with my openHAB install. Let me know if I can help test anything
@joeyberkovitz Can you provide some guidance on usage of your new alarm functions? I've got your fork cloned locally and been trying to leveage some of your new alarm-specific functions. I've tried passing a my base station device to a couple of them and always get back undefined results. I'm a complete novice at javascript but I seem to be at least formatting the function calls correctly. Any help would be appreciated.
Sure
To get alarm devices:
ring.getAlarmDevices(alarm, (alarmDevicesResponse) => {});
To arm/disarm the alarm:
ring.setAlarmMode(alarmObject, securityPanelZid, armMode, bypassSensors, (response) => {})
alarmObject is the base_station object returned by the devices function
securityPanelZid is the alarmDevicesResponse.body[i].general.v2.zid where the alarmDevicesResponse.body[i].general.v2.deviceType is "security-panel" This is based on the getAlarmDevices function response
armMode can be one of "all", "some", or "none". All arms away, some arms home and none disarms
bypassSensors is an array of zid's to be bypassed. These zid's can be retrieved by the getAlarmDevices function.
The other functions are used to send messages through socket.io and could be helpful if you're trying to build in new functionality.
The messages are a little odd because of the socket setup. To get the response from an arm/disarm event you'll need to register a callback on 'DataUpdate' Example:
ring.registerAlarmCallback(alarm, 'DataUpdate', (message) => { if(message.msg === "DataUpdate" && message.body[0].device !== undefined && message.body[0].device.v1.mode !== undefined){ console.log(message.body[0].device.v1.mode); } });
A result of the setup of their API is that most callbacks like DataUpdate will be called whenever the mode changes or upon the associated trigger, so you can register that callback, but should expect it to be called multiple times unless you unregister it upon a response.
@joeyberkovitz - this is very interesting information. the single biggest issue folks struggle with is getting timely notifications of a "ding". i don't have a ring alarm, and the location_id
of my ring doorbell is null
(no surprise), but i am wondering if the API you are using has an endpoint that culd be used for non-alarm users. any thoughts? thanks!
I believe that you can assign a location ID your doorbell. Try opening the latest version of the ring app and editing the location of the doorbell. It should ask for a more granular location which should associate the doorbell with the new location ID.
From what I understand the alarm and doorbell APIs are completely independent from each other, so I don't think that you'll be able to get any doorbell related information.
I think you would be more likely to get better ding alerts by trying to figure out how to subscribe to push notifications. Alternatively just poll the dings endpoint, which has been working for me.
thanks! i tried the locationID trick, but no dice, it's still null
it makes sense that the APIs are independent. i am hoping someone can document the API to use for a websocket-based service (since i'm using dave's package for homekit, neither the iOS or android APIs are applicable).
at present, the homekit plugin polls using ding
, but that "makes it rain in the cloud" at times, so websockets is preferred if it ever becomes available.
thanks!
ps: i'll buy a ring alarm and see if i can integrate it into the plugin. that would be cool!
@joeyberkovitz - my ring alarm arrived. do you have anything else to add to this PR?
@joeyberkovitz - also what's the battery in the range extender? the screws on the access panel are frozen on mine... thanks!
I'm a little busy now, but I never built unit tests for it. Also because of the socket system, if you try to set the mode to the current mode, your callback will never get called. There's also some basic functionality like defining sensor attributes, which I didn't investigate much. These changes could be future improvements, but the PR is functional.
The battery is just a standard LiPo
can you send me a picture of the battery? i need the form factor. thanks!
thank you! it's rechargeable, so it probably shipped empty!
I'm circling back to this after some time away (given that my ignorance of javascript was keeping me from making much progress.
Does the PR work right now? I passed my base_station object to the getAlarmDevices function and the API is returning a 403 error (per the doorbot debug messages) and then hangs at "connecting to websocket." Any guesses on whether I'm doing something boneheaded or if Ring changed their API?
I last used it last night and it worked. Can send detailed instructions later
Just an example of some code I use that I can verify is functional for getting the alarm devices (like motion sensors, ...):
ring.devices((e, devices) => {
let alarm = devices.base_stations[0];
ring.getAlarmDevices(alarm, (alarmDevicesResponse) => {
console.log(alarmDevicesResponse);
});
});
Thanks for the follow-up.
It must be something in my account settings or something. I tried your code and it ends up with the exact same result as I was getting before. The ring.devices call returns my base station object but I get a 403 response from the API in the debug logs when I pass that object to getAlarmDevices and then it hangs at the "connecting to websocket" line.
On Tue, Oct 16, 2018, 9:38 PM joeyberkovitz notifications@github.com wrote:
Just an example of some code I use that I can verify is functional for getting the alarm devices (like motion sensors, ...):
ring.devices((e, devices) => { let alarm = devices.base_stations[0]; ring.getAlarmDevices(alarm, (alarmDevicesResponse) => { console.log(alarmDevicesResponse); }); });
— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/davglass/doorbot/issues/26#issuecomment-430458727, or mute the thread https://github.com/notifications/unsubscribe-auth/AQjS3NqtxzxL_x6ZXtvSbEkKCUDlkVKaks5ulooOgaJpZM4VXTzz .
Are you by any chance logging in using a pre-existing token?
No, I figured it out. When I was defining the ringAPI call, you need to set the API version to 11 if you want the alarm functions you added to work. I guess it lets you call the main devices function using an older version but subsequent calls to the alarm API want a newer version of the API (evidently at least v11). When I add that api_version to the ringAPI definition, it works as expected and returned the list of alarmobjects you described.
Thanks again for this code set. Time to see if I can adapt it for my specific needs.
On Wed, Oct 17, 2018, 7:47 AM joeyberkovitz notifications@github.com wrote:
Are you by any chance logging in using a pre-existing token?
— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/davglass/doorbot/issues/26#issuecomment-430596689, or mute the thread https://github.com/notifications/unsubscribe-auth/AQjS3DwCpY2h88ZePgq4HnEkdnqGT_ahks5ulxi0gaJpZM4VXTzz .
@joeyberkovitz - i finally have had an opportunity to take a look at this!
what i am interested in is getting updates via websockets when sensors change status. is there a way to register for that?
You should be able to do that. I haven't investigated the messages sent back too much, but I think DataUpdate is the one you need:
ring.registerAlarmCallback(alarm, 'DataUpdate', (message) => { if(message.msg === "DataUpdate" && message.body[0].device !== undefined && message.body[0].device.v1.mode !== undefined){ console.log(message.body[0].device.v1.mode); } });
That callback will be called every time Ring sends an update, which I think it periodically does.
thanks! i'll try it out...
outside of re-using a couple of internal calls, there really isn't much overlap in the functionality. i'm going to create a new repository that focuses on this new functionality... please stay tuned!
Are you using a socket.io compatible client in C#?
Socket.io isn't a standard socket or websocket, it's a custom protocol built on top of web sockets.
I just got the alarm and tried to connect to that API.
I discovered some info about the API, but had problems getting the connection to work It looks like the alarm is associated with a location_id, available in the latest API version Sending a POST request to https://app.ring.com/api/v1/rs/connections with accountId: LOCATION_ID and an authorization header using the same oauth token used during the initial login returns an object with a server to connect to along with an auth code.
The alarm communication then occurs over a websocket, seemingly using socket.io. The websocket URL is: wss://SERVERNAME/socket.io/?authcode=AUTHCODE&ack=false&EIO=3&transport=websocket where SERVERNAME and AUTHCODE come from the connections request
I tried connecting to the socket using the socket.io client, but the connection is closed after the initial frame is received. Following is the code I used to initiate the socket:
io.connect("wss://" + alarmConnection.server + "/socket.io/?authcode=" + alarmConnection.authCode, { transports: ['websocket'], upgrade: false, nsp: '/' } );
Any help would be appreciated
I did some research and it looks like there is a difference when connecting with socket.io that the official ring client doesn't do. Screenshots below: Official Client:
Custom Client: