Giter VIP home page Giter VIP logo

homebridge-logi-circle-controls's Introduction

Homebridge Logitech Circle Controls

This is a Homebridge plugin that exposes extended controls for Logitech Circle cameras, such as toggles for privacy mode, camera on/off, and LED on/off.

This plugin only works with older cameras using Logitech's web service, not newer cameras based on HomeKit Secure Video.

⚠️ Project in Maintenance Mode ⚠️

This project is in maintenance mode and will only receive bug fixes (if I can even do that). No new features are planned.

My Logi Circle stopped working so I'm not able to use this plugin anymore, which makes new feature development very difficult! 😅

Install

npm i -g homebridge-logi-circle-controls

Minimum Requirements

  • Node v12+
  • Homebridge v1.3+

Log In

Run the included command line tool to log into your Logitech account:

homebridge-logi-circle-controls login

Use the -h option to get additional help.

Refer to the "How to Log In" wiki page for more detailed information about how to complete the process.

Homebridge Configuration Path

The tool expects that your Homebridge config.json is located in ~/.homebridge.

If this is not the case (e.g. Synology, Docker, etc.), use the -d option to specify the directory where your config.json is located:

homebridge-logi-circle-controls login -d /path/to/homebridge/config/dir

Configure

In your Homebridge config.json file, add a new entry in platforms that looks like this:

{
  "platform": "Logi Circle Controls",

  /* Optional: overrides for names of accessories the platform provides */
  "nameOverrides": {
    "camera": "<Optional: the desired name of the camera switch | Default: 'Camera'>",
    "led": "<Optional: the desired name of the LED switch | Default: 'LED'>",
    "recording": "<Optional: the desired name of the recording switch | Default: 'Recording'>",
    "nightVisionMode": "<Optional: the desired name of the night vision mode switch | Default: 'Night Vision'>",
    "nightVisionIR": "<Optional: the desired name of the night vision IR switch | Default: 'Night IR'>"
  }
}

homebridge-logi-circle-controls's People

Contributors

klanchman avatar dependabot[bot] avatar

Stargazers

Tuan Duc Tran avatar  avatar Me avatar  avatar Scott Hardwick avatar Sean avatar Konstantin Demblin avatar ik5 avatar Brian Clemens avatar Anthony Patton avatar whatthefilament avatar Curtis Jones avatar Gorka avatar Ben Fysh avatar jlx avatar Jon Darke avatar Thomas Nemec avatar Jessie Bryan avatar  avatar  avatar Nastra avatar

Watchers

James Cloos avatar  avatar  avatar  avatar

Forkers

yxu8888

homebridge-logi-circle-controls's Issues

Camera still showing live feed in Home App.

@klanchman Thank you for creating this plugin. Question...I have Streaming and Privacy switches off, but I'm still able to see the thumbnails every 10 seconds as well as able to stream the feed live within the Home App. The Logi Cicle app seems to be respond accordantly, but Home app seems unaffected.

Determine user agent based on Logitech API info endpoint

I was very lazy with #24 and hardcoded the latest iOS client version. The client hasn't been updated in quite a while, so I figure this will work for a decent amount of time.

However, a better solution would be looking at Logitech's GET /api/info endpoint, which returns a payload like this:

{
  "Version": "1.68.0-31-g5b738a7c8",
  "minVersions": [
    {
      "Name": "iOSClient",
      "Version": "3.3.1"
    },
    {
      "Name": "AndroidClient",
      "Version": "3.3.1"
    },
    {
      "Name": "KryptoCamera",
      "Version": "4.0.352"
    }
  ]
}

The plugin would then be able to use one of the versions found here to construct its User-Agent header.

Convert to being a dynamic platform

With the conversion to OAuth (#26), it's feeling like it'd make more sense for this plugin to be a dynamic platform (example, docs).

I'm not sure exactly what configuration would look like at that point. I'd probably just remove basically all options and expose all controls for all cameras. The plugin would probably support multiple accounts at that point too. The camera name can be pulled from the Logitech API, and I think if someone renames a control from a HomeKit app that would get reflected on the plugin state? I need to figure out how that works. If that all works out, then I think the config.json entry would just be the platform name and nothing else.

Migrate to the public API

A Logitech employee reached out about the plugin. It turns out Logitech now has a public API for the Logi Circle! The public documentation went up about 6 months ago.

Migrating to the public API will make me more confident in any new feature development since I won't be relying on an undocumented API meant only for Logitech's internal use.

There are going to be a few things to do here. I'll check things off as I get them done.

  • Use the OAuth flow for authentication
  • Change all API calls to work with the public API
  • Create documentation for users on how to set up OAuth

I'll probably make at least 2 approaches for the OAuth documentation: one where the user exposes the plugin to the Internet, and another where the user manually intervenes in the auth flow.


References:

Work with Logitech circle view doorbell?

Hi and thanks so much for writing this plugin!

just wanted to know if this works for the circle view doorbell as well. I saw in HomeKit there was a control to turn the actual doorbell off. I would love to be able to put that on a timer so no one wakes my baby during nap time.

Thanks again

Reverse privacy mode switch

Hi @klanchman, is it possible to reverse the "privacyMode" switch? At the moment the state of the "privacyMode" switch is always opposite to what the Logi Circle app shows and this confuses me a lot, i.e. "privacyMode" switch OFF means that the "recording" switch in the Logi app is ON and vice versa. Of course "privacyMode" OFF means "forget about privacy, you are allowed to record" that is why the "recording" switch in the Logi app is ON but in my opinion it would be better to have a switch state which matches the setting in the Logi Circle app.

The state of the "streamingMode" switch already matches the setting (Camera on/off) found in the Logi Circle app and also the "ledPower" switch works identical to its counter part (LED on/off) in the Logi Circle app. That is why I would love to have the "privacyMode" reversed so that it resembles a "recordingMode" switch instead and now can work exactly as its counter part (Recording on/off) in the Logi Circle app.

After being reversed I would subsequently rename the "privacyMode" switch to "recordingMode" and maybe also make things clearer for the "streamingMode" i.e. renaming the latter to "cameraState" or something similar.

streamingMode -> cameraState = Logi Circle App: Camera
privacyMode reversed -> recordingMode = Logi Circle App: Recording
ledPower = Logi Circle App: LED

Camera ID

Hi. How can I get the camera ID. It is updated with HomeKit firmware so I can’t find it in my account. Regards.

Logitech is transitioning mobile app to SSO / OAuth

Logitech pushed out version 3.5 of their iOS app recently, which now uses SSO / OAuth for authentication. This is notable because this plugin relies on the authentication method the mobile app used to use. My assumption is that Logitech will eventually force users to update the app and turn off the old auth mechanism. The plugin will probably need to move to the new auth flow.

I played around with the new app and managed to successfully complete the auth flow manually.

Auth Flow

The SSO flow uses OAuth with PKCE: https://datatracker.ietf.org/doc/html/rfc7636

  1. Generate a code verifier. The code is a random string that must be from 43 to 128 characters long, with only the characters [A-Z] / [a-z] / [0-9] / "-" / "." / "_" / "~". Create the SHA256 hash of the code, and then base64url encode the hash. The resulting value will be called the code challenge.

  2. Visit the login page in a browser.

    https://id.logi.com/?client_id=0499da51-621f-443f-84dc-5064f631f0d0&scope=circle:all&response_type=code&redirect_uri=com.logitech.Circle:%2F%2Flids&code_challenge_method=S256&code_challenge=<code challenge>
    
    • The client_id belongs to the iOS app
  3. Sign into your Logi account. Your browser will be unable to open the resulting page, which is fine. Copy the value of the code query parameter.

  4. Exchange the code from the previous step for an access and refresh token.

    • curl -X "POST" "https://accounts.logi.com/identity/oauth2/token" \
        -H 'Content-Type: application/x-www-form-urlencoded; charset=utf-8' \
        --data-urlencode "grant_type=authorization_code" \
        --data-urlencode "client_id=0499da51-621f-443f-84dc-5064f631f0d0" \
        --data-urlencode "code_verifier=<code verifier>" \
        --data-urlencode "code=<code>" \
        --data-urlencode "redirect_uri=com.logitech.Circle://lids"
      
  5. Use the access token in subsequent API requests to video.logi.com

    • Set the Authorization header to LIDS <access token>
  6. Eventually, the access token will expire. Use the refresh token to get new access and refresh tokens.

    • curl -X "POST" "https://accounts.logi.com/identity/oauth2/token" \
        -H 'Content-Type: application/x-www-form-urlencoded; charset=utf-8' \
        --data-urlencode "grant_type=refresh_token" \
        --data-urlencode "client_id=0499da51-621f-443f-84dc-5064f631f0d0" \
        --data-urlencode "code_verifier=<code verifier>" \
        --data-urlencode "refresh_token=<refresh token>" \
      

Other notes

  • There's a value in the refresh token that looks suspiciously like a timestamp. When treated as one, it points exactly 2 months into the future. I'm assuming this means that refresh tokens expire after 2 months.
  • It looks like the User-Agent header is not being looked at anymore. That said, given that it broke things before (#24), I'm hesitant to stop masquerading as the iOS app for now.
  • I noticed some rate limit related headers, at least for the authentication endpoints.

Implications

There are a few implications about this flow:

  • The access token can probably live in memory, but we should probably persist the refresh token somewhere. Ideally, somewhere safe.
  • We must persist the code verifier for as long as we continue to use refresh tokens generated using that code verifier. It should probably live alongside the refresh token, wherever that ends up.
  • The redirect URI is tied to the client id. Since we'd need to "borrow" the client id from the iOS app, that means we're stuck with a redirect URI that can't go anywhere. This means plugin users will need to perform a manual step of copying the code somewhere. I'm thinking the "best" experience the plugin could offer is a small webpage that can take the user to the Logitech sign in page, and has a text box that accepts the code that gets exchanged for an access token.

How to configure plugin on HOOBS?

Hi, I'm new to hoobs and I'd like to explore this plugin.

I'm struggling to add those command lines in the configuration tab, Terminal is returning "bash: $: command not found".

Would you be able to point me in the right direction?

Thank you,
JG

HomeKit secure video

Looks like once the camera's firmware is updated and you move the camera into HomeKit secure video, you no longer can use the Logi app, which renders this plugin obsolete since its pulling from the Logi API. Do you know if the latest HomeKit API exposes anything that would give us control over the status light, night vision, or power in automations?

Group switches under a device

Refer to @Nastras's comment.

Currently every switch shows up as its own individual device. There should be a way to create one device per Logi Circle camera being controlled, and inside of that have all the switches for that camera.

Looking at other platforms, it looks like I might need to create accessories using the PlatformAccessory constructor.
EDIT: Rather, it looks like I'd need to add multiple services to a single accessory. Right now I create an accessory for each type of switch, I think I'd want to create an accessory per camera, and have a service for each switch on said accessory.

Some good references:

Add support for Homebridge UI

Homebridge has a web UI that plugins can add their own config schema / custom UI to. With #26, configuring the plugin will become more challenging. Supporting the Homebridge UI could be a good way to get the plugin set up.

See here for developer docs: https://developers.homebridge.io/#/custom-plugin-ui

The Nest camera plugin has some similar OAuth hoops to jump through, so looking at how they've done this could give some inspiration as well: https://github.com/Brandawg93/homebridge-nest-cam

Plugin makes many duplicate API requests

The plugin makes as many API requests as it has enabled switches per camera. In other words, if you have 1 camera and all 4 switches enabled, when the Home app refreshes switch statuses, the plugin may make 4 authentication requests, and will make 4 API requests to get accessory state. We can do better 😉

When I do this, I'll probably rework the API client significantly, and may switch from axios to got.

Plugin always fails to authenticate

The plugin is constantly failing to authenticate with Logitech.

I took a closer look at the requests, and it appears that Logitech's API is only allowing a few particular user agents now.

The user agents that are allowed should be available via GET https://video.logi.com/api/info, which right now doesn't seem to reject arbitrary user agents.

Power / Led

Hello, thanks for this little but really useful plugin. Is it possible that you add other features that are not available in HomeKit like power or LED on / off?

Greeting Nastra

Error: ENOENT on Synology

I'm putting this here, in case someone else comes looking for help with a similar issue.

My Homebridge is installed on my Synology, running DSM 7

Executing the standard
homebridge-logi-circle-controls login

returns an error:
Error: ENOENT: no such file or directory, stat '/var/packages/homebridge/home/.homebridge'

After finding the Wiki page in this repo on How to Login (strongly suggest putting that link in the README), I saw what type of directory it was most likely looking for.

By default, when launching Terminal in Homebridge, it lands me in:
/var/packages/homebridge/shares/homebridge

I then executed:
homebridge-logi-circle-controls login -d .

and everything proceeded to work as normal, after restarting.

Great plugin, thanks for your hard work on this!

Switch to TypeScript

The longer I'm away from the plugin, the less I remember about what I wrote. I'm thinking some type information might help. I also just generally find TypeScript more pleasant to work with once it's all set up...

This would probably also be a good time to look into "better" ways to handle getting the Homebridge API stuff (e.g. Service, Characteristic, etc.) available everywhere. I'm thinking some dependency injection with InversifyJS would probably clean things up a bit.

Implement Logitech-provided HomeKit features

Hello @klanchman, would it be possible that you have all the functions Logitech offers put in your plugin? I mean the features that are included in the standard installation in HomeKit like the video stream, speakers, microphone and motion detectors.

The big advantage would be that only one device is displayed if you only connect the camera via your plugin.

Greeting Nastra

Rename package

Why?

Once #1 is complete, this package will be able to do more than just control the privacy mode switch. As such, it's probably a good idea to rename the project for clarity.

For now I'm thinking the new name could be homebridge-logi-circle-controls

Things to do

LUX Interrogation for Circle 2

Now that the circle 2 firmware supports LUX readings, any chance the plugin can be extended to read the current LUX level? The native HK plugin currently does not support this and multiple attempts to ask Logitech to support have gone unanswered. TIA! - Bill

Login on Hoobs

I am trying to log in to my logitech account after install in Hoobs with "$ homebridge-logi-circle-controls login" but it does not recognize the command and keep getting command not found error. Tried leaving the $ but still same error.

Limit API calls made when errors are occurring

A Logitech employee reached out about the plugin. They mentioned that they came across the plugin because of a recent incident where a high amount of traffic was coming from it due to an issue with failing authentication requests being retried indefinitely.

My hunch is that a HomeKit app may exist that is very aggressive in retrying requests to the plugin when the plugin isn't responding / throwing an error.

I'll investigate further, but my initial plan is to keep track of the number of requests that failed since the last successful request. If that count hits a threshold (probably about 3), the plugin will stop all outgoing requests for a period of time (probably about 5 minutes).

Plugin receiving 403 Forbidden errors from Logitech

[3/22/2022, 7:51:23 PM] [Logi Circle Controls] Refreshing access token. Exp: 2022-03-22T15:18:33.000Z Forced? false
[3/22/2022, 7:51:23 PM] [Logi Circle Controls] Outgoing request: POST https://accounts.logi.com/identity/oauth2/token
[3/22/2022, 7:51:24 PM] [Logi Circle Controls] Incoming response: POST https://accounts.logi.com/identity/oauth2/token - 200
[3/22/2022, 7:51:24 PM] [Logi Circle Controls] Outgoing request: GET https://video.logi.com/api/accessories
[3/22/2022, 7:51:24 PM] [Logi Circle Controls] Incoming response: GET https://video.logi.com/api/accessories - 403
[3/22/2022, 7:51:24 PM] [Logi Circle Controls] Error processing request: HTTPError: Response code 403 (Forbidden)

Camera switch not toggling back on

Problem: If the Circle app is used to turn off the camera stream, the camera switch in Home.app correctly turns off. However, if the Circle app is used to turn the camera stream on, the camera switch in Home.app stays off. Toggling it on manually, does nothing as the camera is already on. Toggling it on and off in Home.app directly works though. This could give a Home.app only user the wrong status of the camera if they don't also have access to the Circle app, or if they don't check the Circle app, but used it last to toggle the camera.

iOS Device: iPhone 7 running 12.2 on same WiFi network.
WiFi AP: Meraki MR33
Homebridge Version: 0.4.47
Plugin Version: 2.1.0
Relevant config section:

 {
            "platform": "Logi Circle Controls",
            "name": "<Optional: the desired name for the platform (mostly affects Homebridge logs) | Default: 'Logi Circle Controls'>",
            "email": “[REDACTED]”,
            "password": "[REDACTED]",
            "accessories": [
                {
                    "deviceId": "[REDACTED]",
                    "name": "Dining Room",
                    "camera": {
                        "name": "DR Camera",
                        "disabled": false
                    },
                    "led": {
                        "name": "DR Camera LED",
                        "disabled": false
                    },
                    "privacyMode": {
                        "name": "DR Camera Privacy Mode",
                        "disabled": true
                    },
                    "recording": {
                        "name": "DRT Camera Recording",
                        "disabled": false
                    }
                }
            ]
        }

Cache auth token on disk

Currently every time you start the Homebridge server, the plugin gets a new auth token. The last time I checked, auth tokens were good for 1 week, so it might be a good idea to cache the latest auth token on the disk. That way if the Homebridge server is restarted, the plugin can use the old auth token since it's probably still valid. This will be especially good for development, since I start and stop the server multiple times in the span of minutes.

Reboot Switch

Hello @klanchman, I need to ask you something again. I've been having a problem lately that one or two cameras in homekit are unreachable.

Would it be possible to implement a reboot switch in your plugin via the api?

Thank you .-)

Simplify configuration

Especially after #4 is complete (or potentially while working on that issue), it should be possible to greatly simplify configuration. I'm thinking it would be better to show all available switches for each device, with the ability to customize the name of each switch if desired. The config could potentially look something like this:

{
  "platforms": [
    {
      "platform": "Logi Circle Controls",
      "name": "<Optional: the desired name for the platform (mostly affects Homebridge logs) | Default: 'Logi Circle Controls'>",
      "email": "<Required: the email for your Logitech Circle account>",
      "password": "<Required: the password for your Logitech Circle account>",
      /* `accessories` is required, defines an array of cameras to control with the platform */
      "accessories": [
        {
          "deviceId": "<Required: the ID of the camera>",
          "name": "<Optional: the desired name of the camera | Default: 'Logi Circle'>",
          /* Each of the below objects would be optional */
          "privacyMode": {
            "name": "<Optional: the desired name of the privacy mode switch | Default: 'Privacy Mode'>"
          },
          "streamingMode": {
            "name": "<Optional: the desired name of the streaming mode switch | Default: 'Streaming Mode'>"
          },
          "ledPower": {
            "name": "<Optional: the desired name of the LED power switch | Default: 'LED Power'>"
          }
        }
        /* Can add more camera objects into the `accessories` array as needed */
      ]
    }
  ]
}

This would make the config much smaller and quicker to write in many cases. For users who don't want to see all the switches for a camera, I'm thinking it should be able to be hidden on the client side, otherwise we could add an optional disabled: <bool> attribute for each of the switch config objects.

Investigate faster updating of switch status

The Home app doesn't seem to ask the plugin to refresh switch status very often. This can lead to the Home app being out of sync if the switches were changed in Logitech's app. Need to investigate how to handle this.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.