Skip to content

Conversation

@cozybuild
Copy link
Owner

@cozybuild cozybuild commented Jan 19, 2025

TODO:

@istathar
Copy link

anything I can do to help?

@cozybuild
Copy link
Owner Author

Thanks, I think I can find some time next weekend to continue this. Then I would appreciate your help with testing

@Cfomodz
Copy link
Contributor

Cfomodz commented Feb 22, 2025

Happy to help if needed 😃
Just ran into the changing the IP in 1 action changes the IP in all actions and was about to write some hack before finding out this was already mostly done it sounds.

@mathias-ewald
Copy link

Waiting for this eagerly :D If you need help, let me know. I just don't want to spend time on it that might just get merged as is tomorrow :D

@DavidVallaLope
Copy link
Collaborator

DavidVallaLope commented May 5, 2025

Hi there! I was testing the current work. So far the functionality works without major issue. I noticed that there are some settings overlap when changing one light configuration. This is originating from reading from the settings where the brightness, temperature and status of the light is saved "globally" instead per device.

{
    "file-version": "2.0",
    "settings": {
        "light_active": 0,
        "brightness": 21,
        "temperature": 236
    }
}

Does the settings allow to store config based on the IP/Device name? Something like this:

{
    "file-version": "2.0",
    "settings": {
        "10.0.0.1": {
            "device_name:": "KeyLight 1"
            "light_active": 0,
            "brightness": 21,
            "temperature": 236
        },
        "10.0.0.2": {
            "device_name:": "KeyLight 2"
            "light_active": 0,
            "brightness": 22,
            "temperature": 156
        }
    }
}

That way we can store device wise configuration without affecting other devices configuration

Edit: I just have checked the Singleton implementation to get the current configuration from the Keylight API. Then, is it possible to have the IP assigned over each knob?

@DavidVallaLope
Copy link
Collaborator

I believe if we switch from the Plugin_base configuration to action_base configuration we can achieve individual IP per action? Will try to implement it and push over here so it can be tested

@DavidVallaLope
Copy link
Collaborator

Hi there, I was able to implement the get_data_from_light method and use it to fetch and update the data of each light individually:
image
(Right now works for toggle and Brightness control)
So far the IP is stored per Dial and that allows to control each Light individually. Right now there is a race issue where if rotating the Dial is too fast, the request to update the brightness/temperature get overwritten with previous values.

I tried pushing the commits under the same branch so they can be tested but seems that I don't have access to modify the repository, therefore I have forked the project so you guys can review it

https://github.com/DavidVallaLope/StreamControllerElgatoKeyLight

@cozybuild
Copy link
Owner Author

Amazing, time flies, thank you very much for this. You should have an invite for accessing this repo

@DavidVallaLope
Copy link
Collaborator

Perfect, now changes should be on this repository. I will add through the day the remaining functionality for the Dial and check on the race thing with the requests.

For testing purposes, what works right now is the Dial Brightness and Toggle so if anybody wants to test it, please do

On update_light implementation, changed the requirement to request the
elgato api to fetch the current values, to use the class properties
@DavidVallaLope
Copy link
Collaborator

I have added the temperature control and as well added the current_status properties to avoid calling the get_data_light method every time an update is needed.
Right now I see certain options to start optimizing the API calls to avoid the race situation with the Dial Requests.
On Toggle action for buttons I can see that the event request (GET) 3 times (to retrieve current configuration, which can be definitely optimized) and 1 (PUT) request to finally update the status of the light.
I can see the same behavior on Dial Rotation events.
image

On the other hand, I observed than on Dial Push the requests are pilling up. A lot of GET request and even 3 PUT requests (which have the same information). This could affect performance as well.
image

I will check that on tomorrow and as well to implement the Icon Update with the current_status class property (as we are not using local settings anymore)

Please feel free to test the changes and let me know anything you find

- New implementation of a json-object for local cache to avoid requesting
to elgato API every operation
- Add set_property method to apply changes into json-object and request
- Change request implementation, TODO async lockeable request
@DavidVallaLope
Copy link
Collaborator

DavidVallaLope commented May 7, 2025

I'm back with good news! I was able to reduce the requests per execution, which increased the performance on the Dials actions. I tried implementing a thread lock mechanism but it was not necessary after removing the unnecessary request being made. There are some occasions that requests get trapped and sent in bulk but the updates happens anyway.

As well included the original Temperature values from the Control Center software.
image

Currently there is a bug that was introduced with the change of how the updates were done in the Keylight, each type of Action acquires a different type of data for the current status of the keylight, which means that on press, it will affect the current configuration of the brightness, temperature or status. This happens due to how StreamController handles the objects assigned to each key and how we are handling the cached json value (object wise and not class wise), if we try to change it class wise it will affect others light configuration so we need to find a way to have one cached json for each IP regardless of which object is accessing for it

As well this bug overwrites the current configuration every time StreamController is restarted.

Will work on the bug after work, hopefully is something easy like implementing getter/setter or change the approach of cache configuration.

The issue with the icons is still happening, will try to check into that once the status bug is solved

Feel free to test the new changes

@DavidVallaLope
Copy link
Collaborator

DavidVallaLope commented May 7, 2025

Getting back into this before I lost this idea, I would write a REDIS based cache logic to store the current settings for all the buttons for specific IP. This should be faster than reading through a file and we would still be able to use the current implementation without affecting multiple lights at once. Will commit the implementation once done.
The previous approach wont work without a Redis server which is not possible.

If anyone has another idea please let us know so we can include that in the design for the json data manipulation

@DavidVallaLope
Copy link
Collaborator

DavidVallaLope commented May 8, 2025

Ended up adding a data dictionary with each IP associated to store locally all configurations making the gets and puts faster, right now almost all the interactions with the Dial feels really smoothly. So far only affected actions are: Toggle and Dial Brightness and Temperature. Tomorrow will add for the remaining 2 actions and call it a day

image

I notice a bug related to the IP's list where sometimes the action will take the first available IP instead of the stored one. We might need to refactor to take the dial settings IP and avoid the overwriting. Other than that I havent found any other bug related to implementation

TODO

  • Add the request based settings to Increase/Decrease and Set Properties actions
  • Fix the icons update process
  • Fix the IP overlapping for actions
  • Clean functions and unused code

Please let me know your thoughts and please test out the changes and let us know the bugs you find

CC. @cozybuild

@istathar
Copy link

istathar commented May 8, 2025

I'd be happy to try testing this, but I'd probably need instructions of how to run this from a checkout as opposed to however the main app pulls in plugins.

@DavidVallaLope
Copy link
Collaborator

Hi @istathar! Thx for checking into this, in order to test the plugin you will have to do the following steps (you need to know the data folder of the StreamController, you can get that information going into StreamController > Open Settings > Developer > Data path, I will refer to this data path as $SC_DIR).

  1. Uninstall the Control Center plugin (if you have it installed) through the store.
  2. git clone the current repository into $SC_DIR/plugins (a folder named StreamControllerElGatoKeylight should be created)
  3. cd StreamControllerElGatoKeylight
  4. Run git checkout multi-light-support to switch to the current branch
  5. Restart StreamController

After that you should get all the changes made on this branch

@DavidVallaLope DavidVallaLope added the enhancement New feature or request label May 8, 2025
@DavidVallaLope
Copy link
Collaborator

DavidVallaLope commented May 9, 2025

Hi!
A quick update on this, the race situation referred on #7 was solved by changing the way method update_icon() was being invoked each time the update happened, now it is launching an Event() that calls the update_icon() for every child of class Core()

As per the IP functionality, seems intermittent to me, but there are times where the IP on the second device gets overwritten to the IP of the first device when trying to set up an action. Seems to me to be just a visual bug since its not affecting functionality but we will need to test more

@DavidVallaLope
Copy link
Collaborator

As of know I believe only code cleaning is necessary. If somebody test this and finds a bug please let me know

@cozybuild
Copy link
Owner Author

Thank you so much for all of your amazing work @DavidVallaLope! Really good stuff! I only have an issue (which is not really plugin-related) with the pre-selection of entries.

  1. Have one light in the list
  2. Create a new button action
  3. The existing device is in the list and looks like it's selected, but the value is not used (button doesn't work)

So you have to select another entry in the list and switch back to the original entry. Can you reproduce the issue?
And the icon for the button is missing. Dial controller is fine.

caesarakalaeii and others added 2 commits October 19, 2025 19:53
  Core.py:

  1. Line 113 - Fixed typo: Changed return data[ip] → return Core.data[ip]
  2. Lines 134-167 - Added null-safety to all property getters:
    - current_status, current_brightness, current_temperature
    - Now check for None IP addresses and failed API calls
    - Return safe defaults instead of crashing
  3. Lines 60-87 - Added null-safety to set_property():
    - Validates IP address exists before accessing data
    - Handles missing data gracefully
  4. Lines 94-113 - Added null-safety to _send_to_api():
    - Checks for None IP address
    - Validates data exists before sending
    - Improved error messages
  5. Lines 291-298 - Fixed preselect_device_by_ip() crash:
    - Added if not hasattr(self, 'device_list'): return check
  6. Lines 221-227 - Removed obsolete modify_brightness() and modify_temperature() methods that tried to use non-existent setters
  7. Line 254 - Fixed toggle_light():
    - Changed to use self.set_property("on", None)
  8. Lines 294-299 - Added IP address validation in on_ip_address_added():
    - Uses imported ipaddress.ip_address() for validation
  9. Lines 42-51 - Removed unused self.json_data instance variable

  SetButton.py:

  10. Lines 94, 99 - Fixed live update to use set_property():
    - Changed self.current_brightness = ... → self.set_property("brightness", ...)
    - Changed self.current_temperature = ... → self.set_property("temperature", ...)
@mike3nl
Copy link

mike3nl commented Jan 6, 2026

Hi @cozybuild and @DavidVallaLope
Any news about this plugin?
I ask because i have three lights now and it would be amazing to get it running.

Amazing work until now.

@caesarakalaeii
Copy link

Thanks for merging my PR 💐
I've been using that version for quite some time now with two lights and haven't seen any issues, so I'd regard it safe. Anything you'd want changed before hand?

@cozybuild
Copy link
Owner Author

Perfect, thanks for testing! I'm rarely on my Linux streaming environment at the moment, sorry about that. But I'll boot into it this week, merge it, and build a new version.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants