[WITHDRAWN] Unofficial Ring Integration

image

@codahq "Started tinkering with getting thumbnails" hmmmm. Care to clarify what this actually means and how we can assist with this?

It doesn't mean anything yet. I'm putting in the API calls we need for thumbnails. I'm going to eventually pull an image, base64 encode it and store it as a base64 string in state I think. I haven't proofed any of that though. It's just groundwork.

3 Likes

If you need some code for that take a look at my old Arlo Pilot app for SmartThings. I was doing that very same things. Until Arlo made ST disable the app.

Anyone having an issue controlling the floodlight can lights recently? I can't seem to control get them to turn on or off from either the device page or the dashboard tile. When I click on the dashboard tile, it just says "sending..." but doesn't do anything. Was working great about a week ago. I've updated the app and driver codes to the most recent versions, tried rebooting, still nothing.

The lights works fine for me on both my wired floodlight cameras to turn on/off.

This is the one I have:
kind: hp_cam_v1

Yeah I've got the same. It's strange because I'm getting motion activity from them just fine but can't control the lights. I may try removing them and re-pairing them later.

I logged out and logged back in and that seemed to do it. Not sure what was wrong but it's working again.

Also, @codahq, if you were somehow able to get the thumbnails to work I'd be forever in your debt. Would love to get thumbnails on a dashboard.

My Ring Alarm integration is still working. Should I update anyway?

My floodlights are working as they should..

1 Like

Howdy

Battery as reported via HE is 79%
image

Via Ring it appears to be more like 50%
image

I haven't checked others
Thoughts?

You can if you want. The alarm integration is not affected by the session timeout because it quickly grabs the websocket information and connects it. If it needs to get the websocket connected it grabs a session again. Mostly, the affected devices are going to be cameras, chimes and doorbells aka everything that doesn't go over the websocket and requires a session to be valid all of the time.

The one benefit the app code now has is that if you do hit rate limiting it gives up instead of pushing you farther over the edge.

1 Like

Ring doesn't use as many icons as Hubitat. If Ring showed you a raw value it would be what you are seeing in Hubitat. In fact, I saw somewhere in the response a string value aka full, low, etc. and I only remember seeing two or three values. That means they probably only have two or three icons.

@codahq
A couple nights ago (real late and very tired) I read the post about "Bad News everyone", so I removed the Ring Integration App, but left the drivers.

So tonight I setup Ring Integration App again, updated all the drivers that need to be. But I noticed every time I click on "initialize" in the Ring API Virtual Devices. In HE logs, is shows my Ring Freeze and Flood sensor as an "Unsupported Device".

I don't even see it listed with all the other devices, that are listed with in the Ring API Virtual Device.

Am I doing something wrong this time around?

Thanks for any info.

I never wrote a flood sensor driver so you must have not noticed it wasn't added the first time. I don't have a flood sensor. (I also don't have a panic button or tilt sensor so there aren't drivers for those either.) Somebody can send me a sensor or somebody can contribute a driver.

I might try writing a driver without the device but the prospect does not excite me. I own all of the devices I have drivers for so far. I even own most of the cameras and doorbells. It's hard to maintain code for devices I don't own. This is already a labor of love. With the vast number of possible devices the integration can support I'm not going to buy them all. So, hopefully somebody steps up and contributes a driver for the ones I don't.

Did you happen to port this over to Hubitat? I haven't looked to see if we have access to the classes to do this yet. I don't even know what those classes would be but I'm assuming Java has stuff to do this in the JDK if Groovy doesn't so we should be okay. Like I said though... I haven't proofed any of it yet. I reversed the calls that the apps use to get thumbnails and that's all I've done so far.

For thumbnails my biggest concern is not feasibility because I have a feeling we can get them. I'm more worried about the performance impacts of doing it. I've already noticed that big log writes (in any app/device) slow the hub down. I would have to guess that big data writes (read images) would probably do the same thing. I have 10 cameras. I think I'm going to make it "enablable" per camera (like the light status polling). But I would also then probably need to determine if they can be done all together or they have to be staggered. If they have to be staggered then it's just going to be annoying because then I have to communicate between devices or manage the schedule in the app, blah, blah.

Not a problem, I must have missed it before then.
Thanks again for all your hard work!

Yes and no... I have some parts of it working, but switched all but a couple cameras from Arlo to UniFi. I also have trouble keeping the Arlo eventsocket connected. It always disconnects after 1 minute, while on a browser it stays connected.

I think everything should work here..

In ArloPilot, I had the device driver do the actual refresh and download of the actual image...

/*
	refresh
	Retreives the latest snapshot image URL from the Arlo cloud for the device.
*/
def refresh()
{
	def imgUrl = parent.getLastImageURL(getDataValue("arloDeviceId"))
	if (!imgUrl)
	{
		logError "refresh: Could not execute getLastImageURL for Arlo device " + getDataValue("arloDeviceId")
		state.lastImage = ""
		return
	}

	// Check for URL changes
	if (imgUrl == state.lastImageUrl)
	{
		logTrace "refresh: Nothing to refresh. The Arlo cloud returned no new image."
		return
	}

	// Fetch the latest image and store it
	try
	{
		httpGet(imgUrl)
		{ response ->
			if (response.status == 200 && response.headers.'Content-Type'.contains("image/jpeg"))
			{
				def imageBytes = response.data
				if (imageBytes)
				{
					def imageName = getImageName()
					try
					{
						// Only store the image if it's changed
						def imageMD5 = getImageMD5(imageBytes)
 						if (state.lastImageMd5 != imageMD5)
						{
							logTrace "refresh: Storing updated image from ArloCloud.  MD5: ${imageMD5}"

							storeImage(imageName, imageBytes)
							state.lastImage = imageName
							state.lastImageUrl = imgUrl
							state.lastImageMd5 = imageMD5
							state.lastRefresh = now()
							def timeString = new Date().format("MM-dd-yy h:mm:ss a", location.timeZone)
							sendEvent(name: "lastRefresh", value: timeString, displayed: false)
						}
						else logTrace "refresh: Image from ArloCloud has not changed.  MD5: ${imageMD5}"
					}
					catch (errorException)
					{
						logError "refresh: Error storing image ${imageName}: ${errorException}"
					}
				}
			}
			else
			{
				logError "refresh: Could not get image; image not available or not a valid jpeg response"
			}
		}
	}
	catch (errorException)
	{
		logDebug "refresh: Error making request; ${errorException}"
	}
}

storeImage() is what did the work in SmartThings to update the carousel tile.. Thats a ST-specific call..

I created an MD5 routine to detect when the image changed.. This was to avoid re-downloading the image if the still hadn't updated... And to avoid being flagged by Arlo for too many API calls.

/*
	getImageMD5
	Generates a unique MD5 hash for ByteArrayInputStream [imageBytes]
*/
import java.security.MessageDigest;
private getImageMD5(ByteArrayInputStream imageBytes)
{
	MessageDigest md5Digest = MessageDigest.getInstance("MD5")
	byte[] byteBuffer = new byte[1024]
	int bytesRead = 0

	while (bytesRead != -1)
	{
		bytesRead = imageBytes.read(byteBuffer)
		if (bytesRead > 0)
		{
			md5Digest.update(byteBuffer, 0, bytesRead)
		}
	}

	imageBytes.reset();
	imageBytes.skip(0);

	def md5 = new BigInteger(1, md5Digest.digest()).toString(16).padLeft(32, '0')
    return md5.toString()
}

In the SmartApp, I enabled an endpoint so the thumbnails could be viewed externally without having to login to the Arlo cloud...

/*
	getLatestStill
	Outputs the latest saved Arlo still image as a binary stream for the camera specified by [params.deviceid].
	Added: v1.4
*/
def getLatestStill()
{
	def deviceId = params.deviceid
	ByteArrayInputStream imageBytes

	if (deviceId)
	{
		imageBytes = getChildDevice("ArloPilot_${deviceId}")?.getLastImageBytes()
	}

	if (!imageBytes)
	{
		return false
	} 
	render contentType: "image/jpeg", data: imageBytes
}

Like storeImage, getImage is a ST specific call too.. Both just manage where the byte arrays are stored. The storage issue is going to be the hard one to solve... I don't know how big the thumbs will be... You might want to consider just creating a proxy where you download and render them to the client.

It looks like all of the needed classes are available on the platform so I think you'll be good there.

Good luck to you!

1 Like

Anybody else notice that their floodlight no longer responds to On/Off commands?

Last events registered were on 12/18.

Edit: Looks like relogging in fixed it. :slight_smile:

Happy Holidays!

1 Like

Hi,

Has anybody been able to use the Ring Pathlight motion sensing?.. that if it detects motion.. it will trigger a light switch to turn on? I created webhooks for the ring doorbell, ring spotlight cam.. but I am unable to choose the motion detection of choice to be the pathlights or ring bridge?

Thanks in advance,

Pathlights doesn't use IFTTT webhooks, it uses websocket so you'll need to install the Ring API Virtual Device and the Ring Beams Bridge device first. Next on the Ring Beams Bridge device, click on the "Create Devices" option to create the Pathlight device which will work over Websocket to get motion/switch and other events.

2 Likes