From 22882da67f1fee235c8b0e3b027d44bac114c3d9 Mon Sep 17 00:00:00 2001 From: Tristyn Russelo Date: Wed, 30 Sep 2026 19:35:24 -0600 Subject: [PATCH 1/4] Keep the requested mode after set_mode() OpenRGB 1.0 applies SDK writes on a per-controller thread but answers REQUEST_CONTROLLER_DATA right away, so the update() in set_mode() can return the previous mode. set_color() and set_colors() then dispatch on that stale mode, and when it has no colors (e.g. Off) they send nothing. Home Assistant hits this every time it turns a light on from Off. See https://gitlab.com/CalcProgrammer1/OpenRGB/-/work_items/5924 Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01Bs25H1VRVY917EZg6GxZhr --- openrgb/orgb.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/openrgb/orgb.py b/openrgb/orgb.py index ea1b4ed..c638a5b 100644 --- a/openrgb/orgb.py +++ b/openrgb/orgb.py @@ -334,6 +334,8 @@ def set_mode(self, mode: Union[str, int, utils.ModeData], save: bool = False, fo ) self.comms.send_data(data) self.update() + # OpenRGB 1.0+ can answer update() before it has applied the new mode + self.active_mode = mode.id def set_custom_mode(self): ''' From 19996abafb9b1244d97845d0304a19b458eaee7e Mon Sep 17 00:00:00 2001 From: Jack Hughes Date: Wed, 7 Oct 2026 23:36:16 -0500 Subject: [PATCH 2/4] Poll for mode change confirmation in set_mode() --- openrgb/orgb.py | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/openrgb/orgb.py b/openrgb/orgb.py index c638a5b..754f122 100644 --- a/openrgb/orgb.py +++ b/openrgb/orgb.py @@ -1,6 +1,7 @@ from __future__ import annotations import struct import platform +import time import warnings from openrgb import utils from typing import Union, Any, Optional @@ -333,9 +334,17 @@ def set_mode(self, mode: Union[str, int, utils.ModeData], save: bool = False, fo len(data) ) self.comms.send_data(data) - self.update() - # OpenRGB 1.0+ can answer update() before it has applied the new mode - self.active_mode = mode.id + # OpenRGB 1.0+ can answer update() before it has applied the new mode, + # so poll until the server reports the requested mode + for _ in range(5): + self.update() + if self.active_mode == mode.id: + break + time.sleep(0.05) + else: + # Server rejected the request or was too slow to apply it; trust + # the request anyway so color setters still dispatch on it + self.active_mode = mode.id def set_custom_mode(self): ''' From 8ca8d8c045c23a9109fb1949f5d8266942bbd875 Mon Sep 17 00:00:00 2001 From: Tristyn Russelo Date: Wed, 7 Oct 2026 22:54:49 -0600 Subject: [PATCH 3/4] Clean up comments in orgb.py Removed comments about OpenRGB 1.0+ behavior and server response. --- openrgb/orgb.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/openrgb/orgb.py b/openrgb/orgb.py index 754f122..4a42f16 100644 --- a/openrgb/orgb.py +++ b/openrgb/orgb.py @@ -334,16 +334,12 @@ def set_mode(self, mode: Union[str, int, utils.ModeData], save: bool = False, fo len(data) ) self.comms.send_data(data) - # OpenRGB 1.0+ can answer update() before it has applied the new mode, - # so poll until the server reports the requested mode for _ in range(5): self.update() if self.active_mode == mode.id: break time.sleep(0.05) else: - # Server rejected the request or was too slow to apply it; trust - # the request anyway so color setters still dispatch on it self.active_mode = mode.id def set_custom_mode(self): From 50f7b82f76b3d0c4cb358982b0cb5f943af1bc80 Mon Sep 17 00:00:00 2001 From: Jack Hughes Date: Wed, 7 Oct 2026 23:58:36 -0500 Subject: [PATCH 4/4] Warn when the mode change doesn't land in set_mode() --- openrgb/orgb.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/openrgb/orgb.py b/openrgb/orgb.py index 4a42f16..8e0c6a0 100644 --- a/openrgb/orgb.py +++ b/openrgb/orgb.py @@ -340,6 +340,9 @@ def set_mode(self, mode: Union[str, int, utils.ModeData], save: bool = False, fo break time.sleep(0.05) else: + warnings.warn( + f"Device {self.name} did not confirm mode change to " + f"{mode.name!r}, setting it anyways") self.active_mode = mode.id def set_custom_mode(self):