Skip to content

Commit

Permalink
Hue labs not supported by V2 API, removed.
Browse files Browse the repository at this point in the history
Ambilight force on is no longer needed as Hue API V2 will now turn the lights on without error if they are off.
Finish ambigroup implementation
Improve settings reloading and core execution loop
  • Loading branch information
zim514 committed Dec 26, 2023
1 parent ee88d76 commit c1da472
Show file tree
Hide file tree
Showing 9 changed files with 158 additions and 690 deletions.
10 changes: 6 additions & 4 deletions script.service.hue/addon.xml
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,12 @@
</assets>
<source>https://github.com/zim514/script.service.hue</source>
<forum>https://forum.kodi.tv/showthread.php?tid=344886</forum>
<news>v1.5
- Hue API V2 Scenes (requires reconfiguration)
- Hue API V2 Sunset support. Sunrise is now manually configured (Default 8AM)
- Refactoring
<news>v1.5 (beta)
- Hue API V2 support
- Now uses standard scenes (requires reconfiguration)
- Sunrise is now manually configured (Default 8AM)
- Removed some unnecessary settings
- Refactoring and code improvements
</news>
<summary lang="ca_ES">Automatitza les llums Hue amb la reproducció de Kodi</summary>
<summary lang="cs_CZ">Automatizace Hue světel s přehráváním Kodi</summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,6 @@ msgctxt "#30047"
msgid "Connection lost. Check settings. Shutting down"
msgstr "Connection lost. Check settings. Shutting down"


msgctxt "#30050"
msgid "N-UPnP discovery..."
msgstr "N-UPnP discovery..."
Expand All @@ -254,10 +253,6 @@ msgctxt "#30056"
msgid "Set brightness on start"
msgstr "Set brightness on start"

msgctxt "#30057"
msgid "Force on"
msgstr "Force on"

msgctxt "#30058"
msgid "Light Names:"
msgstr "Light Names:"
Expand Down Expand Up @@ -414,10 +409,6 @@ msgctxt "#30073"
msgid "Do not show again"
msgstr ""

msgctxt "#30074"
msgid "Disable Hue Labs during playback"
msgstr ""

msgctxt "#30001"
msgid "Hue Bridge V1 (Round) is unsupported. Hue Bridge V2 (Square) is required."
msgstr ""
Expand Down Expand Up @@ -473,4 +464,16 @@ msgstr ""
#. Amount of time for the light scene transition to fade in, in seconds.
msgctxt "#31335"
msgid "Transition time (seconds):"
msgstr ""
msgstr ""

msgctxt "#30002"
msgid "Bridge overloaded, stopping ambilight"
msgstr ""

msgctxt "#30025"
msgid "Bridge unauthorized, please reconfigure."
msgstr ""

msgctxt "#30026"
msgid "Connection failed, retrying..."
msgstr ""
252 changes: 80 additions & 172 deletions script.service.hue/resources/lib/ambigroup.py

Large diffs are not rendered by default.

14 changes: 7 additions & 7 deletions script.service.hue/resources/lib/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

from . import ADDON, SETTINGS_CHANGED, ADDONID, AMBI_RUNNING
from . import lightgroup, kodiutils, ambigroup
from .huev2 import HueAPIv2
from .hue import Hue
from .kodiutils import validate_settings, notification, cache_set, cache_get, convert_time
from .language import get_string as _

Expand Down Expand Up @@ -51,7 +51,7 @@ def handle_command(self, command, *args):
raise RuntimeError(f"Unknown Command: {command}")

def discover(self):
bridge = HueAPIv2(self.monitor, discover=True)
bridge = Hue(self.monitor, discover=True)
if bridge.connected:
xbmc.log("[script.service.hue] Found bridge. Opening settings.")
ADDON.openSettings()
Expand All @@ -62,15 +62,15 @@ def discover(self):

def scene_select(self, light_group, action):
xbmc.log(f"[script.service.hue] sceneSelect: light_group: {light_group}, action: {action}")
bridge = HueAPIv2(self.monitor)
bridge = Hue(self.monitor)
if bridge.connected:
bridge.configure_scene(light_group, action)
else:
xbmc.log("[script.service.hue] No bridge found. sceneSelect cancelled.")
notification(_("Hue Service"), _("Check Hue Bridge configuration"))

def ambi_light_select(self, light_group):
bridge = HueAPIv2(self.monitor)
bridge = Hue(self.monitor)
if bridge.connected:
bridge.configure_ambilights(light_group)
else:
Expand All @@ -81,7 +81,7 @@ def ambi_light_select(self, light_group):
class HueService:
def __init__(self, monitor):
self.monitor = monitor
self.bridge = HueAPIv2(monitor)
self.bridge = Hue(monitor)
self.light_groups = []
self.timers = None
self.service_enabled = True
Expand Down Expand Up @@ -131,8 +131,8 @@ def run(self):
def initialize_light_groups(self):
# Initialize light groups
return [
lightgroup.LightGroup(0, self.bridge, lightgroup.VIDEO),
lightgroup.LightGroup(1, self.bridge, lightgroup.AUDIO),
lightgroup.LightGroup(0, lightgroup.VIDEO, self.bridge),
lightgroup.LightGroup(1, lightgroup.AUDIO, self.bridge),
ambigroup.AmbiGroup(3, self.monitor, self.bridge)
]

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,9 @@
from .language import get_string as _


class HueAPIv2(object):
class Hue(object):
def __init__(self, monitor, discover=False):
self.scene_data = None
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) # Old hue bridges use insecure https

self.session = requests.Session()
Expand All @@ -45,7 +46,7 @@ def __init__(self, monitor, discover=False):
self.connected = self.connect()
else:
xbmc.log("[script.service.hue] No bridge IP or user key provided. Bridge not configured.")
notification(_("Hue Service"), _("Bridge not configured. Please check your settings."), icon=xbmcgui.NOTIFICATION_ERROR)
notification(_("Hue Service"), _("Bridge not configured"), icon=xbmcgui.NOTIFICATION_ERROR)

def reload_settings(self):
self.ip = ADDON.getSetting("bridgeIP")
Expand Down Expand Up @@ -85,24 +86,24 @@ def make_api_request(self, method, resource, discovery=False, **kwargs):
# Handle HTTP errors
if x.response.status_code == 429:
# If a 429 status code is received, abort and log an error
xbmc.log(f"[script.service.hue] v2 make_request: Too Many Requests: {x}. Aborting request.")
notification(_("Hue Service"), _("Bridge not found. Please check your network or enter IP manually."), icon=xbmcgui.NOTIFICATION_ERROR)
xbmc.log(f"[script.service.hue] v2 make_request: Too Many Requests: {x} \nResponse: {x.response.text}")
return 429
elif x.response.status_code in [401, 403]:
xbmc.log(f"[script.service.hue] v2 make_request: Unauthorized: {x}")
xbmc.log(f"[script.service.hue] v2 make_request: Unauthorized: {x}\nResponse: {x.response.text}")
notification(_("Hue Service"), _("Bridge unauthorized, please reconfigure."), icon=xbmcgui.NOTIFICATION_ERROR)
ADDON.setSettingString("bridgeUser", "")
return None
return 401
elif x.response.status_code == 404:
xbmc.log(f"[script.service.hue] v2 make_request: Not Found: {x}")
xbmc.log(f"[script.service.hue] v2 make_request: Not Found: {x}\nResponse: {x.response.text}")
return 404
elif x.response.status_code == 500:
xbmc.log(f"[script.service.hue] v2 make_request: Internal Bridge Error: {x}")
xbmc.log(f"[script.service.hue] v2 make_request: Internal Bridge Error: {x}\nResponse: {x.response.text}")
return 500
else:
xbmc.log(f"[script.service.hue] v2 make_request: HTTPError: {x}")
xbmc.log(f"[script.service.hue] v2 make_request: HTTPError: {x}\nResponse: {x.response.text}")
return x.response.status_code
except (Timeout, json.JSONDecodeError) as x:
xbmc.log(f"[script.service.hue] v2 make_request: Timeout/JSONDecodeError: {x}")
xbmc.log(f"[script.service.hue] v2 make_request: Timeout/JSONDecodeError: Response: {x.response.text}\n{x}")
except requests.RequestException as x:
# Report other kinds of RequestExceptions
xbmc.log(f"[script.service.hue] v2 make_request: RequestException: {x}")
Expand All @@ -121,7 +122,7 @@ def make_api_request(self, method, resource, discovery=False, **kwargs):
def _discover_new_ip(self):
if self._discover_nupnp():
xbmc.log(f"[script.service.hue] v2 _discover_and_handle_new_ip: discover_nupnp SUCCESS, bridge IP: {self.ip}")
self.ip = self.bridge_ip
# TODO: add new discovery methods here
ADDON.setSettingString("bridgeIP", self.ip)
if self.connect():
xbmc.log(f"[script.service.hue] v2 _discover_and_handle_new_ip: connect SUCCESS")
Expand All @@ -140,6 +141,8 @@ def connect(self):
self.connected = False
return False

self.scene_data = self.make_api_request("GET", "scene")

self.bridge_id = self.get_device_by_archetype(self.devices, 'bridge_v2')
if self._check_version():
self.connected = True
Expand Down Expand Up @@ -457,12 +460,12 @@ def search_dict(d, key):
return d[key]
for k, v in d.items():
if isinstance(v, dict):
item = HueAPIv2.search_dict(v, key)
item = Hue.search_dict(v, key)
if item is not None:
return item
elif isinstance(v, list):
for d in v:
if isinstance(d, dict):
item = HueAPIv2.search_dict(d, key)
item = Hue.search_dict(d, key)
if item is not None:
return item
Loading

0 comments on commit c1da472

Please sign in to comment.