コード例 #1
0
    def check_active_time():
        service_enabled = CACHE.get(f"{ADDONID}.service_enabled")
        daylight = CACHE.get("script.service.hue.daylight")
        # xbmc.log("[script.service.hue] Schedule: {}, daylightDisable: {}, daylight: {}, startTime: {}, endTime: {}".format(ADDON.getSettingBool("enableSchedule"), ADDON.getSettingBool("daylightDisable"), daylight,
        #           ADDON.getSettingBool("startTime"), ADDON.getSettingBool("endTime")))

        if ADDON.getSettingBool("daylightDisable") and daylight:
            xbmc.log("[script.service.hue] Disabled by daylight")
            return False

        if service_enabled:
            if ADDON.getSettingBool("enableSchedule"):
                start = convert_time(ADDON.getSettingString("startTime"))
                end = convert_time(ADDON.getSettingString("endTime"))
                now = datetime.datetime.now().time()
                if (now > start) and (now < end):
                    # xbmc.log("[script.service.hue] Enabled by schedule")
                    return True
                # xbmc.log("[script.service.hue] Disabled by schedule")
                return False
            # xbmc.log("[script.service.hue] Schedule not enabled")
            return True

        # xbmc.log("[script.service.hue] Service disabled")
        return False
コード例 #2
0
def _error_report_dialog(exc):
    response = xbmcgui.Dialog().yesnocustom(heading=_("Hue Service Error"), message=_("The following error occurred:") + f"\n[COLOR=red]{exc}[/COLOR]\n" + _("Automatically report this error?"), customlabel=_("Never report errors"))
    if response == 2:
        xbmc.log("[script.service.hue] Error Reporting disabled")
        ADDON.setSettingBool("error_reporting", False)
        return False
    return response
コード例 #3
0
def menu():
    route = sys.argv[0]
    addon_handle = int(sys.argv[1])
    base_url = sys.argv[0]
    command = sys.argv[2][1:]
    parsed = parse_qs(command)

    logger.debug(
        "Menu started.  route: {}, handle: {}, command: {}, parsed: {}, Arguments: {}"
        .format(route, addon_handle, command, parsed, sys.argv))

    if route == "plugin://script.service.hue/":
        if not command:

            build_menu(base_url, addon_handle)

        elif command == "settings":
            logger.debug("Opening settings")
            ADDON.openSettings()

        elif command == "toggle":
            if cache.get("script.service.hue.service_enabled"
                         ) and get_status() != "Disabled by daylight":
                logger.info("Disable service")
                cache.set("script.service.hue.service_enabled", False)

            elif get_status() != "Disabled by daylight":
                logger.info("Enable service")
                cache.set("script.service.hue.service_enabled", True)
            else:
                logger.info("Disabled by daylight, ignoring")

            xbmc.executebuiltin('Container.Refresh')

    elif route == "plugin://script.service.hue/actions":
        action = parsed['action'][0]
        kgroupid = parsed['kgroupid'][0]
        logger.debug("Actions: {}, kgroupid: {}".format(action, kgroupid))
        if action == "menu":
            items = [
                (base_url + "?action=play&kgroupid=" + kgroupid,
                 ListItem(_("Play"))),
                (base_url + "?action=pause&kgroupid=" + kgroupid,
                 ListItem(_("Pause"))),
                (base_url + "?action=stop&kgroupid=" + kgroupid,
                 ListItem(_("Stop"))),
            ]

            xbmcplugin.addDirectoryItems(addon_handle, items, len(items))
            xbmcplugin.endOfDirectory(handle=addon_handle, cacheToDisc=True)

        else:
            cache.set("script.service.hue.action", (action, kgroupid),
                      expiration=(timedelta(seconds=5)))

    else:
        logger.error(
            "Unknown command. Handle: {}, route: {}, Arguments: {}".format(
                addon_handle, route, sys.argv))
コード例 #4
0
def _validate_ambilight():
    logger.debug("Validate ambilight config. Enabled: {}".format(
        settings_storage['ambiEnabled']))
    if settings_storage['ambiEnabled']:
        if settings_storage['zones'] == "0":
            light_ids = ADDON.getSetting("group3_Lights")
            if light_ids == "-1":
                logger.error("No ambilights selected")
                xbmcgui.Dialog().notification(
                    _("Hue Service"),
                    _("No lights selected for Ambilight."),
                    icon=xbmcgui.NOTIFICATION_ERROR)
                ADDON.setSettingBool("group3_enabled", False)
                settings_storage['ambiEnabled'] = False
        if settings_storage['zones'] == "1":
            light_idsLeft = ADDON.getSetting("group3_LightsLeft")
            if light_idsLeft == "-1":
                logger.error("No ambilights selected for left zone")
                xbmcgui.Dialog().notification(
                    _("Hue Service"),
                    _("No lights selected for Ambilight in left zone."),
                    icon=xbmcgui.NOTIFICATION_ERROR)
                ADDON.setSettingBool("group3_enabled", False)
                settings_storage['ambiEnabled'] = False
            light_idsRight = ADDON.getSetting("group3_LightsRight")
            if light_idsRight == "-1":
                logger.error("No ambilights selected for right zone")
                xbmcgui.Dialog().notification(
                    _("Hue Service"),
                    _("No lights selected for Ambilight in right zone."),
                    icon=xbmcgui.NOTIFICATION_ERROR)
                ADDON.setSettingBool("group3_enabled", False)
                settings_storage['ambiEnabled'] = False
コード例 #5
0
    def __init__(self, monitor, silent=True, discover=False):
        self.bridge = None
        self.bridge_ip = ADDON.getSettingString("bridgeIP")
        self.bridge_user = ADDON.getSettingString("bridgeUser")
        self.monitor = monitor
        self.connected = False

        if discover:
            self.discover_bridge()
        else:
            self.connect_bridge(silent)
コード例 #6
0
    def connect_bridge(self, silent=False):

        xbmc.log(
            f"[script.service.hue] in connect_bridge() with settings: bridgeIP: {self.bridge_ip}, bridgeUser: {self.bridge_user}"
        )

        if self.bridge_ip and self.bridge_user:
            if not self._check_version():
                xbmc.log(
                    "[script.service.hue] in connect_bridge(): Bridge not responding to connection test, attempt finding a new bridge IP."
                )

                if self._discover_bridge_ip():
                    xbmc.log(
                        f"[script.service.hue] in connect_bridge(): New IP found: {self.bridge_ip}. Saving"
                    )
                    ADDON.setSettingString("bridgeIP", self.bridge_ip)
                else:
                    xbmc.log("[script.service.hue] Bridge not found")
                    notification(_("Hue Service"),
                                 _("Bridge connection failed"),
                                 icon=xbmcgui.NOTIFICATION_ERROR)
                    self.connected = False
                    return

            xbmc.log("[script.service.hue] in Connect(): Checking User")
            if self._check_user():
                bridge = qhue.Bridge(self.bridge_ip,
                                     self.bridge_user,
                                     timeout=QHUE_TIMEOUT)
                self.connected = True
                self.bridge = bridge
                xbmc.log(
                    f"[script.service.hue] Successfully connected to Hue Bridge: {self.bridge_ip}"
                )
                if not silent:
                    notification(_("Hue Service"),
                                 _("Hue connected"),
                                 sound=False)
                return
            else:
                xbmc.log("[script.service.hue] Bridge not responding")
                notification(_("Hue Service"),
                             _("Bridge connection failed"),
                             icon=xbmcgui.NOTIFICATION_ERROR)
                self.connected = False

        else:
            xbmc.log("[script.service.hue] Bridge not configured")
            notification(_("Hue Service"),
                         _("Bridge not configured"),
                         icon=xbmcgui.NOTIFICATION_ERROR)
            self.connected = False
コード例 #7
0
def _validate_ambilight():
    xbmc.log(
        f"[script.service.hue] Validate ambilight config. Enabled: {ADDON.getSettingBool('group3_enabled')}"
    )
    if ADDON.getSettingBool("group3_enabled"):
        light_ids = ADDON.getSetting("group3_Lights")
        if light_ids == "-1":
            ADDON.setSettingBool("group3_enabled", False)
            xbmc.log("[script.service.hue] No ambilights selected")
            notification(_("Hue Service"),
                         _("No lights selected for Ambilight."),
                         icon=xbmcgui.NOTIFICATION_ERROR)
コード例 #8
0
 def _bridge_error500(self):
     self.bridge_error500 = self.bridge_error500 + 1  # increment counter
     if self.bridge_error500 > 50 and ADDON.getSettingBool("show500Error"):
         AMBI_RUNNING.clear()  # shut it down
         stop_showing_error = xbmcgui.Dialog().yesno(
             _("Hue Bridge over capacity"),
             _("The Hue Bridge is over capacity. Increase refresh rate or reduce the number of Ambilights."
               ),
             yeslabel=_("Do not show again"),
             nolabel=_("Ok"))
         if stop_showing_error:
             ADDON.setSettingBool("show500Error", False)
         self.bridge_error500 = 0
コード例 #9
0
def _validate_schedule():
    xbmc.log(
        f"[script.service.hue] Validate schedule. Schedule Enabled: {ADDON.getSettingBool('enableSchedule')}"
    )
    if ADDON.getSettingBool("enableSchedule"):
        try:
            convert_time(ADDON.getSettingString("startTime"))
            convert_time(ADDON.getSettingString("endTime"))
            # xbmc.log("[script.service.hue] Time looks valid")
        except ValueError as e:
            ADDON.setSettingBool("EnableSchedule", False)
            xbmc.log(f"[script.service.hue] Invalid time settings: {e}")
            notification(_("Hue Service"),
                         _("Invalid start or end time, schedule disabled"),
                         icon=xbmcgui.NOTIFICATION_ERROR)
コード例 #10
0
    def check_keep_lights_off_rule(self, scene):
        if not scene:
            return True

        xbmc.log(
            f"[script.service.hue] Check if lights should stay off, settings: enable {ADDON.getSettingBool('keep_lights_off')}"
        )
        if ADDON.getSettingBool("keep_lights_off"):
            try:
                scene_data = self.bridge.scenes[scene]()
                for light in scene_data["lights"]:
                    l = self.bridge.lights[light]()
                    if l["state"][
                            "on"] is False:  # one light is off, the scene should not be applied
                        xbmc.log(
                            "[script.service.hue] Check if lights should stay off: True"
                        )
                        return False
                xbmc.log(
                    "[script.service.hue] Check if lights should stay off: False"
                )
            except QhueException as exc:
                xbmc.log(
                    f"[script.service.hue] checkKeepLightsOffRule: Hue call fail: {exc.type_id}: {exc.message} {traceback.format_exc()}"
                )
                reporting.process_exception(exc)
            except requests.RequestException as exc:
                xbmc.log(f"[script.service.hue] Requests exception: {exc}")
                notification(header=_("Hue Service"),
                             message=_(f"Connection Error"),
                             icon=xbmcgui.NOTIFICATION_ERROR)

        return True
コード例 #11
0
    def check_already_active(self, scene):
        if not scene:
            return False

        xbmc.log(
            f"[script.service.hue] Check if scene light already active, settings: enable {ADDON.getSettingBool('enable_if_already_active')}"
        )
        if ADDON.getSettingBool("enable_if_already_active"):
            try:
                scene_data = self.bridge.scenes[scene]()
                for light in scene_data["lights"]:
                    l = self.bridge.lights[light]()
                    if l["state"][
                            "on"]:  # one light is on, the scene can be applied
                        # xbmc.log("[script.service.hue] Check if scene light already active: True")
                        return True
                # xbmc.log("[script.service.hue] Check if scene light already active: False")
            except QhueException as exc:
                if ["7", "3"] in exc.type_id:
                    xbmc.log("[script.service.hue] Scene not found")
                    notification(_("Hue Service"),
                                 _("ERROR: Scene not found"),
                                 icon=xbmcgui.NOTIFICATION_ERROR)
                else:
                    xbmc.log(
                        f"[script.service.hue] checkAlreadyActive: Hue call fail: {exc.type_id}: {exc.message} {traceback.format_exc()}"
                    )
                    reporting.process_exception(exc)
            except requests.RequestException as exc:
                xbmc.log(f"[script.service.hue] Requests exception: {exc}")
                notification(header=_("Hue Service"),
                             message=_(f"Connection Error"),
                             icon=xbmcgui.NOTIFICATION_ERROR)

        return False
コード例 #12
0
def _validate_schedule():
    logger.debug("Validate schedule. Schedule Enabled: {}".format(
        settings_storage['enableSchedule']))
    if settings_storage['enableSchedule']:
        try:
            convert_time(settings_storage['startTime'])
            convert_time(settings_storage['endTime'])
            logger.debug("Time looks valid")
        except ValueError as e:
            logger.error("Invalid time settings: {}".format(e))

            xbmcgui.Dialog().notification(
                _("Hue Service"),
                _("Invalid start or end time, schedule disabled"),
                icon=xbmcgui.NOTIFICATION_ERROR)
            ADDON.setSettingBool("EnableSchedule", False)
            settings_storage['enableSchedule'] = False
コード例 #13
0
    def __init__(self,
                 light_group_id,
                 hue_connection,
                 media_type,
                 initial_state=STATE_STOPPED,
                 video_info_tag=xbmc.InfoTagVideo):
        self.light_group_id = light_group_id
        self.bridge = hue_connection.bridge
        self.enabled = ADDON.getSettingBool(
            f"group{self.light_group_id}_enabled")

        self.start_behavior = ADDON.getSettingBool(
            f"group{self.light_group_id}_startBehavior")
        self.start_scene = ADDON.getSettingString(
            f"group{self.light_group_id}_startSceneID")

        self.pause_behavior = ADDON.getSettingBool(
            f"group{self.light_group_id}_pauseBehavior")
        self.pause_scene = ADDON.getSettingString(
            f"group{self.light_group_id}_pauseSceneID")

        self.stop_behavior = ADDON.getSettingBool(
            f"group{self.light_group_id}_stopBehavior")
        self.stop_scene = ADDON.getSettingString(
            f"group{self.light_group_id}_stopSceneID")

        self.state = initial_state
        self.media_type = media_type
        self.video_info_tag = video_info_tag
        self.last_media_type = self.media_type
        self.lights = self.bridge.lights
        self.group0 = self.bridge.groups[0]

        if self.enabled:
            super().__init__()
コード例 #14
0
def _get_status_icon():
    enabled = CACHE.get(f"{ADDONID}.service_enabled")
    daylight = CACHE.get(f"{ADDONID}.daylight")
    daylight_disable = ADDON.getSettingBool("daylightDisable")
    # xbmc.log("[script.service.hue] Current status: {}".format(daylight_disable))
    if daylight and daylight_disable:
        return xbmcvfs.makeLegalFilename(ADDONPATH + "resources/icons/daylight.png")  # Disabled by Daylight
    elif enabled:
        return xbmcvfs.makeLegalFilename(ADDONPATH + "resources/icons/enabled.png")  # Enabled
    return xbmcvfs.makeLegalFilename(ADDONPATH + "resources/icons/disabled.png")  # Disabled
コード例 #15
0
def _get_status():
    enabled = CACHE.get(f"{ADDONID}.service_enabled")
    daylight = CACHE.get(f"{ADDONID}.daylight")
    daylight_disable = ADDON.getSettingBool("daylightDisable")
    # xbmc.log("[script.service.hue] Current status: {}".format(daylight_disable))
    if daylight and daylight_disable:
        return _("Disabled by daylight")
    elif enabled:
        return _("Enabled")
    return _("Disabled")
コード例 #16
0
def get_string(t):
    string_id = _strings.get(t.lower())
    if not string_id:
        xbmc.log(f"[script.service.hue] LANGUAGE: missing translation for '{t.lower()}'")
        return t

    if STRDEBUG:
        return f"STR:{string_id} {ADDON.getLocalizedString(string_id)}"

    return ADDON.getLocalizedString(string_id)
コード例 #17
0
def menu():
    route = sys.argv[0]
    addon_handle = int(sys.argv[1])
    base_url = sys.argv[0]
    command = sys.argv[2][1:]
    parsed = parse_qs(command)

    if route == f"plugin://{ADDONID}/":
        if not command:
            build_menu(base_url, addon_handle)

        elif command == "settings":
            ADDON.openSettings()

        elif command == "toggle":
            if CACHE.get(f"{ADDONID}.service_enabled") and _get_status() != "Disabled by daylight":
                xbmc.log("[script.service.hue] Disable service")
                CACHE.set(f"{ADDONID}.service_enabled", False)

            elif _get_status() != "Disabled by daylight":
                xbmc.log("[script.service.hue] Enable service")
                CACHE.set(f"{ADDONID}.service_enabled", True)
            else:
                xbmc.log("[script.service.hue] Disabled by daylight, ignoring")

            xbmc.executebuiltin('Container.Refresh')

    elif route == f"plugin://{ADDONID}/actions":
        action = parsed['action'][0]
        light_group_id = parsed['light_group_id'][0]
        xbmc.log(f"[script.service.hue] Actions: {action}, light_group_id: {light_group_id}")
        if action == "menu":

            xbmcplugin.addDirectoryItem(addon_handle, base_url + "?action=play&light_group_id=" + light_group_id, ListItem(_("Play")))
            xbmcplugin.addDirectoryItem(addon_handle, base_url + "?action=pause&light_group_id=" + light_group_id, ListItem(_("Pause")))
            xbmcplugin.addDirectoryItem(addon_handle, base_url + "?action=stop&light_group_id=" + light_group_id, ListItem(_("Stop")))

            xbmcplugin.endOfDirectory(handle=addon_handle, cacheToDisc=True)
        else:
            CACHE.set(f"{ADDONID}.action", (action, light_group_id), expiration=(timedelta(seconds=5)))
    else:
        xbmc.log(f"[script.service.hue] Unknown command. Handle: {addon_handle}, route: {route}, Arguments: {sys.argv}")
コード例 #18
0
    def configure_ambilights(self, group_id):
        lights = self.select_hue_lights()
        light_names = []
        color_lights = []
        if lights is not None:
            for L in lights:
                light_names.append(self._get_light_name(L))
                color_lights.append(L)

            ADDON.setSettingString(f"group{group_id}_Lights",
                                   ','.join(color_lights))
            ADDON.setSettingString(f"group{group_id}_LightNames",
                                   ', '.join(light_names))
            ADDON.setSettingBool(f"group{group_id}_enabled", True)
            ADDON.openSettings()
コード例 #19
0
def activate(light_groups):
    """
    Activates play action as appropriate for all groups. Used at sunset and when service is re-enabled via Actions.
    """
    xbmc.log(
        f"[script.service.hue] Activating scenes: light_groups: {light_groups}"
    )

    for g in light_groups:
        xbmc.log(
            f"[script.service.hue] in activate g: {g}, light_group_id: {g.light_group_id}"
        )
        if ADDON.getSettingBool(f"group{g.light_group_id}_enabled"):
            g.activate()
コード例 #20
0
 def configure_scene(self, group_id, action):
     scene = self.select_hue_scene()
     if scene is not None:
         # group0_startSceneID
         ADDON.setSettingString(f"group{group_id}_{action}SceneID",
                                scene[0])
         ADDON.setSettingString(f"group{group_id}_{action}SceneName",
                                scene[1])
         ADDON.openSettings()
コード例 #21
0
    def check_video_activation(self, info_tag):
        try:
            duration = info_tag.getDuration(
            ) / 60  # returns seconds, convert to minutes
            media_type = info_tag.getMediaType()
            file_name = info_tag.getFile()
            if not file_name and self.isPlayingVideo():
                file_name = self.getPlayingFile()
            #
            # if not fileName and previousFileName:
            #     fileName = previousFileName
            # elif fileName:
            #     previousFileName = fileName

            # xbmc.log("[script.service.hue] InfoTag contents: duration: {}, mediaType: {}, file: {}".format(duration, mediaType, fileName))
        except (AttributeError, TypeError) as exc:
            xbmc.log("[script.service.hue] Can't read infoTag {exc}")
            return False
        # xbmc.log("Video Activation settings({}): minDuration: {}, Movie: {}, Episode: {}, MusicVideo: {}, PVR : {}, Other: {}".format(self.light_group_id, settings_storage['videoMinimumDuration'], settings_storage['video_enableMovie'],
        #                settings_storage['video_enableEpisode'], settings_storage['video_enableMusicVideo'], settings_storage['video_enablePVR'], settings_storage['video_enableOther']))
        # xbmc.log("[script.service.hue] Video Activation ({}): Duration: {}, mediaType: {}, ispvr: {}".format(self.light_group_id, duration, mediaType, fileName[0:3] == "pvr"))
        if ((duration >= ADDON.getSettingInt("video_MinimumDuration")
             or file_name[0:3] == "pvr") and
            ((ADDON.getSettingBool("video_Movie") and media_type == "movie") or
             (ADDON.getSettingBool("video_Episode")
              and media_type == "episode") or
             (ADDON.getSettingBool("video_MusicVideo")
              and media_type == "MusicVideo") or
             (ADDON.getSettingBool("video_PVR") and file_name[0:3] == "pvr") or
             (ADDON.getSettingBool("video_Other") and media_type != "movie"
              and media_type != "episode" and media_type != "MusicVideo"
              and file_name[0:3] != "pvr"))):
            xbmc.log("[script.service.hue] Video activation: True")
            return True
        xbmc.log("[script.service.hue] Video activation: False")
        return False
コード例 #22
0
    def __init__(self,
                 light_group_id,
                 hue_connection,
                 initial_state=STATE_STOPPED,
                 video_info_tag=xbmc.InfoTagVideo):
        self.hue_connection = hue_connection
        self.light_group_id = light_group_id
        self.bridge = hue_connection.bridge
        self.monitor = hue_connection.monitor
        self.group0 = self.bridge.groups[0]
        self.bridge_error500 = 0
        self.state = initial_state
        self.enabled = ADDON.getSettingBool(
            f"group{self.light_group_id}_enabled")

        self.saved_light_states = {}
        self.video_info_tag = video_info_tag

        self.image_process = imageprocess.ImageProcess()

        self.converterA = Converter(GamutA)
        self.converterB = Converter(GamutB)
        self.converterC = Converter(GamutC)
        self.helper = ColorHelper(
            GamutC)  # Gamut doesn't matter for this usage

        self.enabled = ADDON.getSettingBool(
            f"group{self.light_group_id}_enabled")

        self.transition_time = int(
            ADDON.getSettingInt(f"group{self.light_group_id}_TransitionTime") /
            100
        )  # This is given as a multiple of 100ms and defaults to 4 (400ms). transition_time:10 will make the transition last 1 second.
        self.force_on = ADDON.getSettingBool(
            f"group{self.light_group_id}_forceOn")
        self.disable_labs = ADDON.getSettingBool(
            f"group{self.light_group_id}_disableLabs")
        self.min_bri = ADDON.getSettingInt(
            f"group{self.light_group_id}_MinBrightness"
        ) * 255 / 100  # convert percentage to value 1-254
        self.max_bri = ADDON.getSettingInt(
            f"group{self.light_group_id}_MaxBrightness"
        ) * 255 / 100  # convert percentage to value 1-254
        self.saturation = ADDON.getSettingNumber(
            f"group{self.light_group_id}_Saturation")
        self.capture_size_x = ADDON.getSettingInt(
            f"group{self.light_group_id}_CaptureSize")
        self.resume_state = ADDON.getSettingBool(
            f"group{self.light_group_id}_ResumeState")
        self.resume_transition = ADDON.getSettingInt(
            f"group{self.light_group_id}_ResumeTransition"
        ) * 10  # convert seconds to multiple of 100ms

        self.update_interval = ADDON.getSettingInt(
            f"group{self.light_group_id}_Interval"
        ) / 1000  # convert MS to seconds
        if self.update_interval == 0:
            self.update_interval = 0.1

        if self.enabled:
            self.ambi_lights = {}
            light_ids = ADDON.getSetting(
                f"group{self.light_group_id}_Lights").split(",")
            index = 0

            if len(light_ids) > 0:
                for L in light_ids:
                    gamut = self._get_light_gamut(self.bridge, L)
                    light = {
                        L: {
                            'gamut': gamut,
                            'prev_xy': (0, 0),
                            "index": index
                        }
                    }
                    self.ambi_lights.update(light)
                    index = index + 1

                super(xbmc.Player).__init__()
コード例 #23
0
def process_exception(exc, level="critical", error=""):
    if ADDON.getSettingBool("error_reporting"):
        if _error_report_dialog(exc):
            _report_error(level, error, exc)
コード例 #24
0
def read_settings():
    settings_storage['disable_connection_message'] = ADDON.getSettingBool(
        "disableConnectionMessage")
    settings_storage['reloadFlash'] = ADDON.getSettingBool("reloadFlash")
    settings_storage['initialFlash'] = ADDON.getSettingBool("initialFlash")
    settings_storage['forceOnSunset'] = ADDON.getSettingBool("forceOnSunset")
    settings_storage['daylightDisable'] = ADDON.getSettingBool(
        "daylightDisable")
    cache.set("script.service.hue.daylightDisable",
              ADDON.getSettingBool("daylightDisable"))

    settings_storage['enableSchedule'] = ADDON.getSettingBool("enableSchedule")
    settings_storage['startTime'] = ADDON.getSetting(
        "startTime")  # string HH:MM
    settings_storage['endTime'] = ADDON.getSetting("endTime")  # string HH:MM
    settings_storage['disableConnectionMessage'] = ADDON.getSettingBool(
        "disableConnectionMessage")

    settings_storage['videoMinimumDuration'] = ADDON.getSettingInt(
        "video_MinimumDuration"
    )  # Setting in Minutes. Kodi library uses seconds, needs to be converted.
    settings_storage['video_enableMovie'] = ADDON.getSettingBool("video_Movie")
    settings_storage['video_enableMusicVideo'] = ADDON.getSettingBool(
        "video_MusicVideo")
    settings_storage['video_enableEpisode'] = ADDON.getSettingBool(
        "video_Episode")
    settings_storage['video_enableOther'] = ADDON.getSettingBool("video_Other")

    settings_storage['ambiEnabled'] = ADDON.getSettingBool("group3_enabled")
    settings_storage['show500Error'] = ADDON.getSettingBool("show500Error")
    _validate_schedule()
    _validate_ambilight()
コード例 #25
0
def notification(header,
                 message,
                 time=5000,
                 icon=ADDON.getAddonInfo('icon'),
                 sound=False):
    xbmcgui.Dialog().notification(header, message, icon, time, sound)
コード例 #26
0
def _commands(monitor, command):
    xbmc.log(f"[script.service.hue] Started with {command}")

    if command == "discover":
        hue_connection = hueconnection.HueConnection(monitor,
                                                     silent=True,
                                                     discover=True)
        if hue_connection.connected:
            xbmc.log("[script.service.hue] Found bridge. Starting service.")
            ADDON.openSettings()
            _service(monitor)
        else:
            ADDON.openSettings()

    elif command == "createHueScene":
        hue_connection = hueconnection.HueConnection(
            monitor, silent=True,
            discover=False)  # don't rediscover, proceed silently
        if hue_connection.connected:
            hue_connection.create_hue_scene()
        else:
            xbmc.log(
                "[script.service.hue] No bridge found. createHueScene cancelled."
            )
            notification(_("Hue Service"), _("Check Hue Bridge configuration"))

    elif command == "deleteHueScene":
        hue_connection = hueconnection.HueConnection(
            monitor, silent=True,
            discover=False)  # don't rediscover, proceed silently
        if hue_connection.connected:
            hue_connection.delete_hue_scene()
        else:
            xbmc.log(
                "[script.service.hue] No bridge found. deleteHueScene cancelled."
            )
            notification(_("Hue Service"), _("Check Hue Bridge configuration"))

    elif command == "sceneSelect":  # sceneSelect=light_group,action  / sceneSelect=0,play
        light_group = sys.argv[2]
        action = sys.argv[3]
        # xbmc.log(f"[script.service.hue] sceneSelect: light_group: {light_group}, action: {action}")

        hue_connection = hueconnection.HueConnection(
            monitor, silent=True,
            discover=False)  # don't rediscover, proceed silently
        if hue_connection.connected:
            hue_connection.configure_scene(light_group, action)
        else:
            xbmc.log(
                "[script.service.hue] No bridge found. sceneSelect cancelled.")
            notification(_("Hue Service"), _("Check Hue Bridge configuration"))

    elif command == "ambiLightSelect":  # ambiLightSelect=light_group_id
        light_group = sys.argv[2]
        # xbmc.log(f"[script.service.hue] ambiLightSelect light_group_id: {light_group}")

        hue_connection = hueconnection.HueConnection(
            monitor, silent=True, discover=False
        )  # don't rediscover, proceed silently  # don't rediscover, proceed silently
        if hue_connection.connected:
            hue_connection.configure_ambilights(light_group)
        else:
            xbmc.log(
                "[script.service.hue] No bridge found. Select ambi lights cancelled."
            )
            notification(_("Hue Service"), _("Check Hue Bridge configuration"))
    else:
        xbmc.log(f"[script.service.hue] Unknown command: {command}")
        raise RuntimeError(f"Unknown Command: {command}")
コード例 #27
0
def _service(monitor):
    hue_connection = HueConnection(
        monitor,
        silent=ADDON.getSettingBool("disableConnectionMessage"),
        discover=False)
    service_enabled = CACHE.get(f"{ADDONID}.service_enabled")

    if hue_connection.connected:
        light_groups = [
            lightgroup.LightGroup(0, hue_connection, lightgroup.VIDEO),
            lightgroup.LightGroup(1, hue_connection, lightgroup.AUDIO),
            ambigroup.AmbiGroup(3, hue_connection)
        ]

        connection_retries = 0
        timer = 60
        daylight = hue_connection.get_daylight()
        new_daylight = daylight

        CACHE.set(f"{ADDONID}.daylight", daylight)
        CACHE.set(f"{ADDONID}.service_enabled", True)
        # xbmc.log("[script.service.hue] Core service starting. Connected: {}".format(CONNECTED))

        while hue_connection.connected and not monitor.abortRequested():

            # check if service was just re-enabled and if so activate groups
            prev_service_enabled = service_enabled
            service_enabled = CACHE.get(f"{ADDONID}.service_enabled")
            if service_enabled and not prev_service_enabled:
                activate(light_groups)

            # if service disabled, stop ambilight._ambi_loop thread
            if not service_enabled:
                AMBI_RUNNING.clear()

            # process cached waiting commands
            action = CACHE.get(f"{ADDONID}.action")
            if action:
                _process_actions(action, light_groups)

            # reload groups if settings changed, but keep player state
            if SETTINGS_CHANGED.is_set():
                light_groups = [
                    lightgroup.LightGroup(
                        0,
                        hue_connection,
                        lightgroup.VIDEO,
                        initial_state=light_groups[0].state,
                        video_info_tag=light_groups[0].video_info_tag),
                    lightgroup.LightGroup(
                        1,
                        hue_connection,
                        lightgroup.AUDIO,
                        initial_state=light_groups[1].state,
                        video_info_tag=light_groups[1].video_info_tag),
                    ambigroup.AmbiGroup(
                        3,
                        hue_connection,
                        initial_state=light_groups[2].state,
                        video_info_tag=light_groups[2].video_info_tag)
                ]
                SETTINGS_CHANGED.clear()

            # every minute, check for sunset & connection
            if timer > 59:
                timer = 0
                # check connection to Hue hue_connection and fetch daylight status
                try:
                    if connection_retries > 0:
                        hue_connection.connect_bridge(silent=True)
                        if hue_connection.connected:
                            new_daylight = hue_connection.get_daylight()
                            connection_retries = 0
                    else:
                        new_daylight = hue_connection.get_daylight()
                except (requests.RequestException, ConnectionError) as error:
                    connection_retries = connection_retries + 1
                    if connection_retries <= 10:
                        xbmc.log(
                            f"[script.service.hue] Bridge Connection Error. Attempt: {connection_retries}/10 : {error}"
                        )
                        notification(
                            _("Hue Service"),
                            _("Connection lost. Trying again in 2 minutes"))
                        timer = -60
                    else:
                        xbmc.log(
                            f"[script.service.hue] Bridge Connection Error. Attempt: {connection_retries}/10. Shutting down : {error}"
                        )
                        notification(
                            _("Hue Service"),
                            _("Connection lost. Check settings. Shutting down")
                        )
                        hue_connection.connected = False

                # check if sunset took place
                if new_daylight != daylight:
                    xbmc.log(
                        f"[script.service.hue] Daylight change. current: {daylight}, new: {new_daylight}"
                    )
                    daylight = new_daylight

                    CACHE.set(f"{ADDONID}.daylight", daylight)
                    if not daylight and service_enabled:
                        xbmc.log("[script.service.hue] Sunset activate")
                        activate(light_groups)
            timer += 1
            monitor.waitForAbort(1)
        xbmc.log("[script.service.hue] Process exiting...")
        return
    xbmc.log("[script.service.hue] No connected hue_connection, exiting...")
    return
コード例 #28
0
    def _ambi_loop(self):
        AMBI_RUNNING.set()
        cap = xbmc.RenderCapture()
        xbmc.log("[script.service.hue] _ambiLoop started")
        aspect_ratio = cap.getAspectRatio()

        self.capture_size_y = int(self.capture_size_x / aspect_ratio)
        expected_capture_size = self.capture_size_x * self.capture_size_y * 4  # size * 4 bytes - RGBA
        xbmc.log(
            f"[script.service.hue] aspect_ratio: {aspect_ratio}, Capture Size: ({self.capture_size_x},{self.capture_size_y}), expected_capture_size: {expected_capture_size}"
        )

        cap.capture(
            self.capture_size_x, self.capture_size_y
        )  # start the capture process https://github.com/xbmc/xbmc/pull/8613#issuecomment-165699101

        for L in list(self.ambi_lights):
            self.ambi_lights[L].update(prev_xy=(0.0001, 0.0001))

        while not self.monitor.abortRequested() and AMBI_RUNNING.is_set(
        ) and self.hue_connection.connected:  # loop until kodi tells add-on to stop or video playing flag is unset.
            try:

                cap_image = cap.getImage(
                )  # timeout to wait for OS in ms, default 1000

                if cap_image is None or len(cap_image) < expected_capture_size:
                    xbmc.log(
                        "[script.service.hue] capImage is none or < expected. captured: {}, expected: {}"
                        .format(len(cap_image), expected_capture_size))
                    self.monitor.waitForAbort(
                        0.25)  # pause before trying again
                    continue  # no image captured, try again next iteration
                image = Image.frombytes(
                    "RGBA", (self.capture_size_x, self.capture_size_y),
                    bytes(cap_image), "raw", "BGRA", 0,
                    1)  # Kodi always returns a BGRA image.

            except ValueError:
                xbmc.log(f"[script.service.hue] capImage: {len(cap_image)}")
                xbmc.log("[script.service.hue] Value Error")
                self.monitor.waitForAbort(0.25)
                continue  # returned capture is smaller than expected, but this happens when player is stopping so fail silently. give up this loop.

            colors = self.image_process.img_avg(image, self.min_bri,
                                                self.max_bri, self.saturation)
            for L in list(self.ambi_lights):
                t = Thread(target=self._update_hue_rgb,
                           name="_update_hue_rgb",
                           args=(colors['rgb'][0], colors['rgb'][1],
                                 colors['rgb'][2], L, self.transition_time,
                                 colors['bri']),
                           daemon=True)
                t.start()

            self.monitor.waitForAbort(self.update_interval)  # seconds

        if not self.monitor.abortRequested(
        ):  # ignore writing average process time if Kodi is shutting down
            average_process_time = self._perf_average(PROCESS_TIMES)
            xbmc.log(
                f"[script.service.hue] Average process time: {average_process_time}"
            )
            ADDON.setSetting("average_process_time", str(average_process_time))
            xbmc.log("[script.service.hue] _ambiLoop stopped")
コード例 #29
0
    def discover_bridge(self):
        xbmc.log("[script.service.hue] Start bridgeDiscover")
        # Create new config if none exists. Returns success or fail as bool
        ADDON.setSettingString("bridgeIP", "")
        ADDON.setSettingString("bridgeUser", "")
        self.bridge_ip = ""
        self.bridge_user = ""

        self.connected = False

        progress_bar = xbmcgui.DialogProgress()
        progress_bar.create(_('Searching for bridge...'))
        progress_bar.update(5, _("Discovery started"))

        complete = False
        while not progress_bar.iscanceled(
        ) and not complete and not self.monitor.abortRequested():

            progress_bar.update(percent=10, message=_("N-UPnP discovery..."))
            bridge_ip_found = self._discover_nupnp()

            if not bridge_ip_found and not progress_bar.iscanceled():
                manual_entry = xbmcgui.Dialog().yesno(
                    _("Bridge not found"),
                    _("Bridge not found automatically. Please make sure your bridge is up to date and has access to the internet. [CR]Would you like to enter your bridge IP manually?"
                      ))
                if manual_entry:
                    self.bridge_ip = xbmcgui.Dialog().numeric(
                        3, _("Bridge IP"))

            if self.bridge_ip:
                progress_bar.update(percent=50, message=_("Connecting..."))
                if self._check_version() and self._check_bridge_model(
                ) and not progress_bar.iscanceled():
                    progress_bar.update(percent=100,
                                        message=_("Found bridge: ") +
                                        self.bridge_ip)
                    self.monitor.waitForAbort(1)

                    bridge_user_created = self._create_user(progress_bar)

                    if bridge_user_created:
                        xbmc.log(
                            f"[script.service.hue] User created: {self.bridge_user}"
                        )
                        progress_bar.update(
                            percent=90,
                            message=_("User Found![CR]Saving settings..."))

                        ADDON.setSettingString("bridgeIP", self.bridge_ip)
                        ADDON.setSettingString("bridgeUser", self.bridge_user)

                        progress_bar.update(percent=100,
                                            message=_("Complete!"))
                        self.monitor.waitForAbort(5)
                        progress_bar.close()
                        xbmc.log(
                            "[script.service.hue] Bridge discovery complete")
                        self.connect_bridge(True)
                        return True

                    elif progress_bar.iscanceled():
                        xbmc.log("[script.service.hue] Cancelled 2")
                        complete = True
                        progress_bar.update(percent=100,
                                            message=_("Cancelled"))
                        progress_bar.close()

                    else:
                        xbmc.log(
                            f"[script.service.hue] User not created, received: {self.bridge_user}"
                        )
                        progress_bar.update(
                            percent=100,
                            message=
                            _("User not found[CR]Check your bridge and network."
                              ))
                        self.monitor.waitForAbort(5)
                        complete = True
                        progress_bar.close()
                        return
                elif progress_bar.iscanceled():
                    xbmc.log("[script.service.hue] Cancelled 3")
                    complete = True
                    progress_bar.update(percent=100, message=_("Cancelled"))
                    progress_bar.close()
                else:
                    progress_bar.update(
                        percent=100,
                        message=_(
                            "Bridge not found[CR]Check your bridge and network."
                        ))
                    xbmc.log(
                        "[script.service.hue] Bridge not found, check your bridge and network"
                    )
                    self.monitor.waitForAbort(5)
                    complete = True
                    progress_bar.close()

            xbmc.log("[script.service.hue] Cancelled 4")
            complete = True
            progress_bar.update(percent=100, message=_("Cancelled"))
            progress_bar.close()

        if progress_bar.iscanceled():
            xbmc.log(
                "[script.service.hue] Bridge discovery cancelled by user 5")
            progress_bar.update(percent=100, message=_("Cancelled"))
            progress_bar.close()