Logi Circle camera with HASS

That’s good to know. I’m inclined to raise the PR for that now in that case.

I might be the worst case for testing Logi Circle connectivity, I’m in Australia where Logi cams aren’t even sold - the data centre my cameras route from is in the US I believe.

My lovelace cards are set up to serve the livestrem on three different types of cameras: A Circle 2, a Foscam, and an Amcrest. If I open 10 copies of the front end, only the logi_circle component opens 10 streams. The other two streams are opened at HA startup and remain open.

I’m pretty sure that is the intended behavior:

From https://www.home-assistant.io/integrations/camera/:

This option will keep the stream alive, and preload the feed on Home Assistant startup. This will result in reduced latency when opening the stream in the frontend, as well as when using the play_stream service or Google Assistant integration. It does, however, utilize more resources on your machine, so it is recommended to check CPU usage if you plan to use this feature.

In fact, it would be a terrible idea to open multi streams to the same camera–that’s too much load to put on a fixed device. This works for logitech (as implemented now) because all the streams go through the cloud.

Again, please excuse my confusion.

It seems like you are overriding the HA Camera class, which is confusing to me.

It automatically handles streams and snapshots from streaming devices. It would then make sense to override async_camera_image so that if the camera is not setup with the stream platform, then you grab Logitech’s JPEG snapshot.

But when the camera is streaming, obtaining a snapshot should be handled by the parent class. As far as I know, given an rtsp url, the HA camera/stream platforms should by themselves handle opening the stream, keeping it open, obtaining snapshots from the stream, and perhaps most importantly, replicating the stream to other devices. E.g., when camera.play_stream plays to a media player, it does not initiate a new rtsp connection.

This is important when the device is serving video locally as we want HA to handle redistributing the stream to multiple receivers.

The Logi Camera entity subclasses the base camera entity, as does every other camera integration (AFAIK).

It is, if you call the camera.snapshot service on the Logi Camera entity.

Logi Circle cameras also ship with their own methods for obtaining snapshots, but they don’t override anything on the base class. They’re used only by logi_circle.livestream_snapshot service.

The differences between these services are documented in that previous link I sent, but in short:

If you’re wondering why I didn’t have camera.snapshot grab the fresh image, it’s because it’s not possible to override the camera.snapshot method from a camera entity. It will always use camera.async_camera_image. And if I changed camera.async_camera_image to always pull a fresh image, it would ravage the battery life of battery powered cam owners because this same method is called when displaying a camera thumbnail on HA’s UI.

The HA camera/stream platforms should by themselves handle opening the stream

It is! In the stream branch, the logi circle cam entity serves an RTSP URL to HA, and then HA does all the heavy lifting to decode and present the stream. What are you seeing that contradicts this?

This is important when the device is serving video locally as we want HA to handle redistributing the stream to multiple receivers.

As far as I know (and I haven’t dug too deep into the stream component) - I haven’t done anything in the camera entity or the API wrapper to interfere with this, if that’s indeed how it works. The Logi Circle camera entity defers to HA for everything that it can. If you can point to any implementation detail that I’ve got wrong that’s getting in the way then I’ll be happy to fix it.

Sorry for my delay in replying on this. I have to figure out if I actually have time to try and play with the camera’s local streaming. I would like to use this as part of an ML stack (face, people, object recognition), so processing snapshots with low latency (< 1sec, ideally) is essential.

Mostly the opening of multiple streams when there are multiple instantiations of the front end (e.g. multiple tabs in chrome). This doesn’t happen for other cameras.

I will check what’s happening and report back.

By the way, isn’t this the point of being able to specify the scan_interval? You could just make it so the default scan interval is 30s, but allowing overrides.

I don’t like this solution for a couple reasons:

  • Forcing cameras to wake on an interval, even a user-specified one, doesn’t necessary fit how these low power cameras would be used. It’s better to allow the camera to be woken up as needed (eg. in response to a event like a doorbell press) instead of draining the battery on a fixed interval. If someone does want it to refresh on an interval, the current implementation supports that - just call the snapshot service in a scheduled HA automation.
  • I want to make the default behaviour non-destructive to battery life of low power cams. Most people don’t read the documentation upfront, I want to avoid nasty surprises.

I think this is the issue:

Starting in the logi_circle component:

async def stream_source(self):
      """Return the stream source."""
        return await self._camera.live_stream.get_rtsp_url()

If we trace self._camera.live_stream.get_rtsp_url(), I believe we will find that every call to it launches an HTTP request to the Logitech API, each time returning a new URL, whereas other camera integrations (e.g., the amcrest integration) cache the url.

If we look in live_stream.py:

    async def get_rtsp_url(self):
        """Get RTSP stream URL."""
        # Request RTSP stream
        url = '%s/%s%s' % (ACCESSORIES_ENDPOINT, self.camera_id, LIVE_RTSP_ENDPOINT)
        stream_resp_payload = await self.logi._fetch(url=url)

        # Return time-limited RTSP URI
        rtsp_uri = stream_resp_payload["rtsp_uri"].replace('rtsp://', 'rtsps://')
        return rtsp_uri

So every time Camera.stream_source() is called, the logi_circle component is returning a new URL. Looking into the stream component, I see that Stream objects are hashed according to their URL.

I think the correct behavior here is that Camera.stream_source() should initiate a connection via the Logitech API, and if that connection is still active on the next call to stream_source(), the cached URL should be returned. Then the stream component will use that URL to lookup the proper stream object and replicate the stream without initiating a new connection.

By the way, this looks correct. I just tried it (with no error checking or anything) by putting
python self._rtsp_url = None in the __init__ of logi_circle/camera.py and changing the code to

    async def stream_source(self):
        """Return the stream source."""
        if not(self._rtsp_url):
            self._rtsp_url = await self._camera.live_stream.get_rtsp_url()
        return self._rtsp_url

And now HA only opens one stream, and that stream is persistent: Closing all front ends and then opening a new one does not initiate a new stream.

It has to. Logi streams are created on-demand, and if nothing uses that stream for 30s, the stream URL is invalidated.

if that connection is still active on the next call to stream_source(), the cached URL should be returned

Even if the URL was still valid (ie. there’s another stream running somewhere that’s consuming the stream data), I’m fairly certain the API blocks new connections on a pre-existing stream after a certain amount of time has elapsed. This is easy enough to test and confirm, so I’ll do that when I get a few mins tonight.

From Logi’s docs:

Get Live RTSP:
This call will return a single use, time limited RTSP URI that must be invoked within 30 seconds.

Yes, that’s fine. The point is that HA keeps the stream open indefinitely. That’s the intention of the stream component. It’s always streaming.

There is no new connection. HA is handling the streaming. An rtsp stream is opened once at HA launch. HA keeps the stream open and reads data from that stream indefinitely. Further “streams” use the same HLS-encoded data that is cached locally by HA.

HA calls Camera.stream_source() to figure out the correct URL to use, and then checks to see if it’s already hashed to a Stream object. The idea here is that if, for some reason, HA drops the connection, a new one can be initiated.

HA calls Camera.stream_source() to figure out the correct URL to use, and then checks to see if it’s already hashed to a Stream object.

OK, that’s useful to know. There are a few problems we’d need to solve first.

  • We’d need to be sure that a RTSP URI is only ever used once, and I’m not sure how we can do that since we don’t know if stream_source() is being called to check the RSTP URI hash or to connect to a new stream. Not everyone will be want their stream running 24/7, and that isn’t even the default behaviour of the stream component.
  • Logitech kills long running streams, so we’d need to catch that and invalidate the cached RTSP URI when that happens. I don’t believe that exception is returned to the camera entity.

Running the stream 24/7 is also probably not what Logitech intended (it’s more demanding on their server, and it kinda replaces their paid subscription), so we’d need to be careful not to upset them otherwise they may start revoking API keys. I can ask about this.

I think that is the default intended behavior of the stream component. I have four different camera models (2 x foscam, 1 x amcrest, 1 x logitech), and the other three also initiate a connection at HA startup and keep it open. Referring to the HA docs:

If your camera supports it, and the stream integration is setup, you will be able to stream your cameras in the frontend and on supported media players.

This option will keep the stream alive, and preload the feed on Home Assistant startup. This will result in reduced latency when opening the stream in the frontend, as well as when using the play_stream service or Google Assistant integration. It does, however, utilize more resources on your machine, so it is recommended to check CPU usage if you plan to use this feature.

I agree that both of these are issues.

They are both solved, I think, if there is some way of validating whether HA has an open connection to that URI. If not, one should generate a new URI through the API.

Running the stream 24/7 is also probably not what Logitech intended (it’s more demanding on their server, and it kinda replaces their paid subscription), so we’d need to be careful not to upset them otherwise they may start revoking API keys. I can ask about this.

Yes, it replaces their paid subscription. So does locally storing the camera data. And so does buying a different camera. I am not particularly worried about upsetting Logitech. I can buy a different camera. They can stop issuing API keys to developers and lose out on free development for their products (why these companies release open APIs in the first place).

Their cameras should have supported local streaming already, and I suspect this wasn’t a priority because they wanted to push the cloud subscription model. But there are major limitations to their implementation, including extreme latency in pulling up a live feed. (For instance, Nest cams work with the same cloud model, but can pull up a live feed in <5s.)

Not for me, I have to click the “Preload stream” checkbox on the live stream to turn it on.

They are both solved, I think, if there is some way of validating whether HA has an open connection to that URI.

Yep, but I don’t think that’s exposed to camera entities right now. So changes to core HA may be required.

I am not particularly worried about upsetting Logitech. I can buy a different camera. They can stop issuing API keys to developers and lose out on free development for their products (why these companies release open APIs in the first place).

I understand, but I don’t want to burn bridges on behalf of everyone like this. I’d rather some functionality than none at all.

Also I think Logi Circle have acted better than most (comparing to other subscription based camera providers: Nest, Ring, Arlo etc) in regards to developer support. Obviously there’s a lot of room for improvement (esp. the poor experience requesting API keys), but for as long as they’re acting in good faith I don’t want to be hostile.

Logitech released an optional firmware update for wired Circle 2 cameras to ‘convert’ them to Apple HomeKit secure video version. After the conversion the cam will not be accessible from Logi Circle app anymore. Only Apple’s Home app can manage the camera. Does this mean if I upgrade the firmware to use it as Homekit Secure Camera, I will loose the cam in Home Assistant as well? As far as I know only an official support request could revert the firmware to the previous version, there is no manual reversion.

Yep. Cameras which are converted to use HomeKit Secure Video disappear from the Logi API afaik.

Hello!

I just got my api keys and I am trying to configure home assistant to use my logi circle 2 cameras. I see the notification:

“We have discovered new devices on your network.”

The Logi Circle is present in the Discovered section, I press configure and I follow the link, authorize and then I get this message:

{
"message": "Authorisation code saved"
}

So far so good. But when i press the SUBMIT button on the integration screen it says:

Please follow the link and authenticate before pressing Submit.

What am I doing wrong?

I don’t see any relevant log entries, only an exception when I close that Configure modal window.

Thank you very much,
Laszlo

1 Like

Maybe a stupid question, but

I’m able to see all my Circle camera’s in HA view, however content are snapshots from the stream whether I click them open or not. I’m confused should I somehow see the live stream (with delay ?) …or not ?

Thanks in advance,

@evanjd any change to the firmware update issue or any work around? In my system I am using the Apple HomeKit app as well as HA. With the recent iOS update the HomeKit app appears to push a consistent notification in the user interface regarding the need to update an accessory. For me the update is the Logi Circle firmware. I can’t get rid of the persistent notification in the HomeKit app…
Is there another way that you are aware of to pull the Logi camera snapshots after the firmware update?

With the recent iOS update the HomeKit app appears to push a consistent notification in the user interface regarding the need to update an accessory. For me the update is the Logi Circle firmware.

The firmware update the Home app is nagging you about is just a regular firmware update, it’s not the HomeKit Secure Video conversion firmware. So it’s completely safe to update, I’ve done so and there were no issues.

It is still the case that you cannot convert your Logi Circle to HomeKit Secure Video and retain the Logi Circle HA integration, per Aron from Logitech a few days ago…

The process is still a one way conversion. After converting your camera to support HomeKit Secure Video you will no longer be able to set up or use this camera in the Circle app on iOS, Android or Web. This also means that your Circle Safe subscription and the associated features will not work. Other integrations such as Alexa and Google Home will not work.

If the camera is invisible to the Circle app, it’s invisible to the Logi Circle API. One day we may be able to integrate the camera via HomeKit’s API, but the current HomeKit integration doesn’t appear to support that right now.