Logi Circle camera with HASS

@evanjd Hi Evan, just digged a bit at your repo - great job!
I do not have any plans for official PR to HASS for logicircle (i just dont have time for this due to other projects :wink: ).

Please note that my implementation is for python 3.5 and up only with focus to make any io as nonblocking async io driven by runloop (i use aiohttp instead of synchronous blocking requests) - this approach considered better and hass actively promotes usage of it.

Also my observations shown that logi changes node-id at some periods of time (i guess due to load balancing of hosting servers), so if you do not retrieve actual node-id, your camera image url become invalid and image retrieval eventually fails - to resolve it you need to get specific camera info before getting actual image - I do it before every fetch of imageā€¦ (url to use is ā€˜https://video.logi.com/api/accessories/{}ā€™.format(self.accessory_id)
) hope this will save you some time )

Best, Sergiy

Hey man, awesome, thanks for the advice. Didnā€™t know about the node ID changing frequently, Iā€™ll update my implementation to re-fetch it each time node ID dependent calls are made.

Good point about aiohttp. I did already have it in the back of my mind to use it when integrating with Home Assistant (I intended to use the url properties for the still image, activity, live stream etc and do the aiohttp request on the hass end), but I donā€™t really care about Python 2.x support, so maybe itā€™s worth refactoring now. Again, thanks for the advice! :smiley:

EDIT: Iā€™m refactoring the API to use aiohttp API exclusively now. Thanks again for the suggestion.

1 Like

Quick update:

  • Iā€™ve published a version of the logi-circle python wrapper to PyPi.
  • Iā€™ve branched home assistant and integrated the logi circle wrapper to create a logi circle platform, camera and sensor component.

Hereā€™s what it looks like:



(mind the mess, weā€™re decluttering :stuck_out_tongue:)

Few things:

  • I only own 1st gen Logi Circle cameras, so thatā€™s all Iā€™ve been able to test with. If someone doesnā€™t mind testing with their 2nd gen camera (indoor or outdoor) thatā€™d be a big help.
  • Similarly, Iā€™ve added support at the python wrapper for reading the celsius and relative humidity values from the camera, but as the 1st gen doesnā€™t include these sensors, I havenā€™t exposed them in the home assistant component (I donā€™t know how they behave, what UoM they use - donā€™t want to risk integrating something thatā€™s broken). If someone wants to help me with this, please message me so I can get some data from you.
  • Iā€™ve added support for downloading the live stream and activities at python-logi-circle, but havenā€™t had success integrating that into HASS (yet). Iā€™m inclined to submit a PR with what I have now and do the live stream and/or activity video in the next iteration. The problem Iā€™m struggling is Iā€™m not sure how to convert MP4 stream into a MJPEG stream. The pattern used on other components is to point FFMPEG at a remote URL and have it handle the conversion, but that wonā€™t work in this case as I need to build the MP4 locally. I could write to a temp file but Iā€™m not sure if thatā€™ll fly when the pull request is being reviewed.

If youā€™re comfortable setting up hass from source, my repo + branch can be checked out with:
git clone -b logi-circle --single-branch https://github.com/evanjd/home-assistant.git

Otherwise Iā€™ll provide a custom component ZIP shortly.

Then add to your configuration:

logi:
  username: [email protected]
  password: yourpassword

camera:
  - platform: logi

sensor:
  - platform: logi
1 Like

Great work! Iā€™ll test it in HASS together with my Circle 2 (outdoor) camera as soon as the custom component is available :slight_smile:

awesome! iā€™ve got 2 logi circle 2 to test! ( actually iā€™m using the still image plugin from @sergeymaysak )
can you please tell me how to install in the HassOS?

Custom components hosted here: https://github.com/evanjd/hass-logi-circle

Iā€™ve added the humidity and temp sensors to the custom component on the off chance someone here gets a value from them. If you do, please let me know if it works correctly and what unit of measure itā€™s using (celsius, fahrenheit, etc).

Just to set/lower expectations, this is still just serving still images. I do intend to show the live stream and/or the last activity once I figure out how to stream that data to hass.

Things Iā€™d love to know:

  • Obviously, does it work?
  • Are all sensors reporting correctly? Please note that the last activity time will use your hass configured timezone, so make sure thatā€™s set correctly.
  • Does the camera.turn_on and camera.turn_off service work correctly? It should enable/disable streaming mode for your camera.
  • What your model number shows up as for each distinct product (eg. my Logi Circle 1st gen shows up as model A1533). Iā€™d like to map these model numbers to real product names if I can. If you click on a sensor, you should see the model number appear in the dialog.
  • Are there any other sensors youā€™d like added? (I will add a binary sensor for motion if I figure out where that data is)

Thanks in advance for taking a look!

EDIT: Just dropped this on my ā€œrealā€ home assistant install to validate - it complained that the logi_circle dependency was missing on first load, but a restart fixed it. :man_shrugging: In case the same thing happens for others, try a restart.

1 Like

This is (hopefully) going to be great for my Logi camera. Here is the json:

{
  "access_token": "redacted",
  "attribution": "Data provided by circle.logi.com",
  "firmware": "5.2.191",
  "model": "V-R0008",
  "timezone": "Europe/Oslo",
  "ip_address": "redacted",
  "mac_address": "redacted",
  "plan": "Circle Free - 24 hours of footage",
  "friendly_name": "Inngang",
  "entity_picture": "/api/camera_proxy/camera.inngang?token=redacted",
  "supported_features": 1,
  "custom_ui_state_card": "state-card-custom-ui"
}

I get the following sensor showing:

Entity State
sensor.logi_inngang_battery -1
sensor.logi_inngang_humidity unknown
sensor.logi_inngang_last_activity 15:38
sensor.logi_inngang_microphone_gain 50
sensor.logi_inngang_privacy_mode off
sensor.logi_inngang_streaming_mode off
sensor.logi_inngang_temperature unknown
sensor.logi_inngang_volume 26
sensor.logi_inngang_wifi_signal_category Excellent
sensor.logi_inngang_wifi_signal_strength 100

I am unable to set the streaming_mode to on, is this the reason why the picture isnā€™t showing when adding camera.inngang as an entity? Also, when I trigger the camera.snapshot, it only gives me the last image saved, not the actual snapshot. Could this have something to do with the streaming mode?

This is my initial response only. I am really grateful for the job youā€™ve put into this and will continue investigating from my part. Please, if you need me to test anything, just send me a PM.

Cheers!

Update: When accessing the api (https://my-url/api/camera_proxy/camera.inngang?token=redacted), I get an 503: Service unavailable as well.

this is mine:

access_token: ā€œredactedā€
attribution: Data provided by circle.logi.com
firmware: 5.2.191
model: V-R0008
timezone: Europe/Rome
ip_address: ā€œredactedā€
mac_address:ā€œredactedā€
plan: Circle Free - 24 hours of footage
friendly_name: Soggiorno
entity_picture: /api/camera_proxy/camera.soggiorno?token=ā€œredactedā€
supported_features: 1

and for the sensor, itā€™s like @vegard ,
adding the entity camera.soggiorno i canā€™t see the still image tooā€¦

I donā€™t know if this is of any use, but here is the GET data from https://video.logi.com/api/accessories/token-key-redacted:

{"accountId":"redacted","accessoryId":"redacted","name":"Inngang","nodeId":"node-i-redacted.video.logi.com","nodeConnectedId":"redacted","messengerId":"prod-api-i-redacted.video.logi.com","messengerConnectedId":"redacted","isConnected":true,"configuration":{"deviceName":"Inngang","modelNumber":"V-R0008","serialNumber":"redacted","firmwareVersion":"5.2.191","firmwareDate":"2018-03-31T00:32:58+00:00","currentTime":"2018-08-22T06:52:30Z","ntpServers":null,"timeInSync":true,"timeZone":"Europe/Oslo","wifiSsid":"redacted","wifiSignalStrength":100,"wifiLevelEventsOn":true,"macAddress":"redacted","ipAddress":"redacted","batteryLevelEventsOn":true,"batteryLevel":-1,"batteryCharging":false,"sensorDimension":{"width":1920,"height":1080},"horizontalFlip":false,"verticalFlip":false,"softwarePtz":{"currentPosition":{"x":224,"y":126,"width":1472,"height":828},"homePosition":{"x":32,"y":18,"width":1856,"height":1044},"maxZoomIn":{"width":480,"height":270},"maxZoomOut":{"width":1856,"height":1044}},"nightVisionMode":"auto","microphoneOn":true,"microphoneGain":50,"speakerOn":false,"speakerVolume":26,"motionDetection":false,"motionDetectionSensitivity":60,"audioDetectionOn":false,"audioDetectionSensitivity":80,"streamingMode":"onAlert","activeStreams":["aac","h264","h264-second","mroi"],"videoStream":{"width":1920,"height":1080,"keyFrameInterval":40,"fps":30,"bitrateKbps":1500,"profile":"main"},"audioStream":{"bitrateKbps":64,"sampleRate":32000},"mjpegStream":{"width":0,"height":0,"keyFrameInterval":0,"quality":0},"videoSecStream":{"width":320,"height":184,"keyFrameInterval":100,"fps":10,"bitrateKbps":150,"profile":"main"},"ledEnabled":false,"bleOff":true,"bleSecKey":"redacted","country":"NO","saveBattery":false,"powerLineFreq":0,"debugMsgToNode":true,"audioFeedbackOn":true,"minTimeAfterAlertSec":8,"motionThreshold":0,"noiseThreshold":0,"connections":[{"connectionName":"1","date":"Sat Aug 04 07:27:03 2018","wifiSsid":"redacted"}],"iqParametersStr":"","iqParametersCrc":"","maxPTTBuffers":5,"adaptiveNoiseDetection":true,"statFilterEnabled":false,"statFilterTimeSlot":0,"statFilterMaxBan":0,"mdAlgo":"logi","privacyMode":false,"cameraMount":"wired","decorativeMount":"","batteryProfile":"","nightVisionIrLedsEnabled":true,"pirMinClipLength":10,"pirMaxClipLength":10,"pirLockoutAfterClip":30,"powerSource":"wired","pirIsAvailable":true,"pirSensitivity":50,"pirTestMode":false,"alsLevel":1.561921,"homekitIsAvailable":true,"homekitEnabled":false,"homekitStatus":"unpaired","pirWakeUp":false,"persistentLog":false,"fastLiveView":false,"wifiLI":0,"buttonIsAvailable":false,"buttonConfig":null,"temperatureIsAvailable":false,"temperature":0,"humidityIsAvailable":false,"humidity":0},"created":"redacted","modified":"2018-08-22T13:37:40.397213Z","certHash":"redacted=","mac":"redacted","macCertSerialNumber":"","accessoryCertSerialNumber":"","notifications":[{"type":"","address":"","priority":0}],"firmwareGroupAccessoryId":"","mediaServiceClass":1,"timezoneOffset":2,"planId":"redacted","planName":"Circle Free - 24 hours of footage","planLastUpdate":"redacted","planLastSync":"redacted","lastUsedIp":"redacted","subscriptionId":"redacted","subscriptionExpiration":"redacted","analysisId":"redacted","location":{"name":"","latitude":"","longitude":"","radius":0,"modifiedBy":""},"modelNumber":"V-R0008","parentSubscriptionId":""}

1 Like

Same error: 503: Service Unavailable

access_token: *
attribution: Data provided by circle.logi.com
firmware: 5.2.191
model: V-R0008
timezone: Europe/Zurich
ip_address: *
mac_address: *
plan: Circle Free - 24 hours of footage
friendly_name: Aquarium
entity_picture: /api/camera_proxy/camera.aquarium_2?token=*
supported_features: 1

sensor.logi_aquarium_battery 98
sensor.logi_aquarium_humidity unknown
sensor.logi_aquarium_last_activity unknown
sensor.logi_aquarium_microphone_gain 0
sensor.logi_aquarium_privacy_mode on
sensor.logi_aquarium_streaming_mode off
sensor.logi_aquarium_temperature unknown
sensor.logi_aquarium_volume 26
sensor.logi_aquarium_wifi_signal_category Fair
sensor.logi_aquarium_wifi_signal_strength 57

Very sorry for the problems, obviously got some work to do support 2nd gen Logi cameras.

Thanks for all the useful info, esp. @vegard for the accessories JSON dump. I can see a few bad assumptions Iā€™ve made:

  • I treat streamingMode as a binary state (on = True, off = False). Didnā€™t know it could return other values (eg. onAlert), Iā€™ll make it a string property instead.
  • I didnā€™t realise the 2nd gen wired cameras had no internal battery. Iā€™ll hide the battery sensors for these cameras.
  • I can see no temp or humidity data is returned on 2nd gen cameras too, must be a placeholder prop for a future product. Iā€™ll remove those sensors.

As for the still image not working, Iā€™ll need to investigate. I assume @sergeymaysak custom component works where mine doesnā€™t here? I can see weā€™re hitting the same endpoint so something must be breaking internally in either the hass component or the API wrapper. Iā€™ll throw @vegardā€™s JSON dump at the wrapper + component and see what breaks, but may need some debugging info if I canā€™t find the issue.

Thanks again for all the help testing.

1 Like

Sorry for not responding. Yes, @sergeymaysakā€™s custom component works fine with the still image. Looking forward to what youā€™ll be able to figure out :slight_smile:

Figured out what went wrong. I was setting the is_on property to false if streamingMode was not ā€œonā€, which I now know is not a valid test for Circle 2nd gens. Home Assistant wonā€™t run the method that grabs the camera image if it thinks the device is off. Thanks again @vegard, wouldnā€™t have figured that out as easily without that JSON dump.

Will have another update out soon. @vegard I may have a solution for your snapshot problem. Iā€™ve started implementing a custom snapshot service (camera.logi_snapshot) that starts the live stream and grabs the first frame from it, instead of using the image home assistant or Logitech cached. Iā€™ve tested a hacked together version of it against the 1st gen and itā€™s ~ 2-3 second latency, so not quite real-time. Iā€™m not sure how itā€™ll behave with 2nd gens, I expect problems, but worth a try.

1 Like

This is great work @evanjd!! I am away for the weekend, but will be able to help out if you need any debug-logs or similar tomorrow night (GMT+2)

hi, any news? I can not wait to try it :grinning:

Yeee me2 :smile:

Sorry, work got busy then my whole family was knocked out with the flu.

Just pushed an update to https://github.com/evanjd/hass-logi-circle

  • 2nd gen cameras should now get an image.
  • Added basic feature detection for sensor setup. For example, if you had a wired camera, you shouldnā€™t get pointless battery sensors.
  • Added logi_livestream_snapshot, logi_download_livestream and logi_set_mode services (see github readme for example usage). In short this allows you to take a snapshot from the livestream instead of the cached image, download the livestream to an MP4, and set various statuses on the camera (LED on/off, privacy mode, etc). Screenshot of example service call below:

  • Removed a few sensors:
    • is_streaming: Not comfortable with this as not sure of all modes set by 2nd gen devices.
    • temperature and humidity: Sensors not on any Logi devices on the market today.
    • speaker_volume and microphone_gain: Unlikely to be of use to anyone.

As an aside, I also got the live stream working from within hass, but havenā€™t figured out yet how to buffer the video, so performance is pretty crappy (you get a few seconds, then it pauses while it grabs the next video segment, rinse and repeat). Iā€™ve left this out of the code I posted, but if youā€™re especially keen for a very crappy implementation of live stream support Iā€™ll slap it into a branch.

Let me know how you go. If you donā€™t get any sensors except last_activity_time, this means that youā€™re using a model I havenā€™t mapped. If this happens, please post your model number and your device name (eg. 2nd gen wired) and Iā€™ll add it in.

EDIT: I should set expectations more appropriately here: as I have no 2nd gen devices to test with, thereā€™s every possibility that some or all of the functionality Iā€™ve implemented still wonā€™t work (the livestream support in particular is at the most risk of not working - thereā€™s every possibility that the stream is implemented differently in 2nd gen devices). Fingers crossed though! If it does fail, would someone consider giving me temporary access to their account so I can implement support? I tried to buy a 2nd gen device, but they donā€™t sell them in Australia and the cost to import is insane ($400ish dollerydoos!)

2 Likes

This is fantastic work @evanjd!
Updated the files and ran a few tests. What I get of entities and sensors are:

camera.entity
sensor.logi_entity_privacy_mode
sensor.logi_entity_wifi_signal_category
sensor.logi_entity_wifi_signal_strength 

I can confirm that both logi_livestream_snapshot and logi_download_livestream works on the 2. gen camera. I have just tested it a few times, but it seems that the the snapshot is pretty instant. I need to run some more test and check, but so far this is so good news! The livestream also works fine, with no errors. A little uncertain if the stream starts recording at the ā€œclick of the buttonā€, I would have to test this a little more.

The sensor last_activity_time is no longer available, is this correct?

Live stream will be a nice addition later on as well, as for now, the instant snapshot is really, really nice :slight_smile:

PS! Later on, I hope you reconsider removing the speaker_volume and microphone_gain. Wouldnā€™t it be cool if the camera could be a media player as well? Then we could send TTS commands to the camera telling the burglars to f**k off with the volum turned to 11 :smiley:

Again, great work, and as always, let me know if you need logs etc.

Cheers, Vegard

EDIT: I have not testet:

Lastly, the camera entity supports the turn_on and turn_off service. turn_off should disable streaming on the target entity (meaning no live stream and no activity recordings), turn_on should activate streaming.

I can confirm that both logi_livestream_snapshot and logi_download_livestream works on the 2. gen camera.

Excellent!

A little uncertain if the stream starts recording at the ā€œclick of the buttonā€, I would have to test this a little more.

It should be as instant as the snapshot is as itā€™s using the same methods in the python-logi-circle library. The only difference is that snapshot takes the first frame of the video and throws away the rest, whereas download livestream obviously keeps the video and appends to it until the desired duration is reached.

The sensor last_activity_time is no longer available, is this correct?

Thatā€™s a mistake - missed that sensor for the feature mapping on 2nd gen wired cams. Will fix in a few hours, thanks for letting me know!

Later on, I hope you reconsider removing the speaker_volume and microphone_gain

I removed these sensors because I couldnā€™t think of a practical purpose to continuously monitor these values. This doesnā€™t stand in the way of implementing speaker support for the camera (on my wishlist), and if I do, those properties would exposed on the speaker entity. Short term my focus will be on polishing what Iā€™ve done so far so that I can raise a PR to hopefully merge this functionality into a future home assistant release.

1 Like

@vegard Update pushed to fix the missing last_activity_time sensor on your camera.

1 Like