From ab59df630778ebd3cf3670042cebd8ae36c46c34 Mon Sep 17 00:00:00 2001 From: Snapcase Date: Fri, 11 Oct 2019 11:04:20 -0400 Subject: [PATCH 1/8] Change performance logging system --- script.service.hue/addon.xml | 2 +- script.service.hue/resources/lib/AmbiGroup.py | 9 ++++++-- .../resources/lib/ImageProcess.py | 22 ++++++++++++++++--- script.service.hue/resources/lib/globals.py | 7 +++++- script.service.hue/resources/lib/kodiHue.py | 14 +++++++++--- script.service.hue/resources/settings.xml | 10 +++++---- 6 files changed, 50 insertions(+), 14 deletions(-) diff --git a/script.service.hue/addon.xml b/script.service.hue/addon.xml index 02dd5dc0..392b2004 100644 --- a/script.service.hue/addon.xml +++ b/script.service.hue/addon.xml @@ -1,4 +1,4 @@ - + diff --git a/script.service.hue/resources/lib/AmbiGroup.py b/script.service.hue/resources/lib/AmbiGroup.py index a7ad4bd7..1a221d90 100644 --- a/script.service.hue/resources/lib/AmbiGroup.py +++ b/script.service.hue/resources/lib/AmbiGroup.py @@ -4,7 +4,6 @@ import xbmc,xbmcgui from PIL import Image -#from . import colorgram #https://github.com/obskyr/colorgram.py from . import ImageProcess from .rgbxy import Converter,ColorHelper# https://github.com/benknight/hue-python-rgb-converter from .rgbxy import XYPoint, GamutA,GamutB,GamutC @@ -17,6 +16,8 @@ from .globals import logger from .language import get_string as _ +from resources.lib import kodiHue + class AmbiGroup(KodiGroup.KodiGroup): @@ -47,6 +48,10 @@ def onPlayBackStopped(self): logger.info("In ambiGroup[{}], onPlaybackStopped()".format(self.kgroupID)) self.state = STATE_STOPPED self.ambiRunning.clear() + averageProcessTime=kodiHue.perfAverage(globals.processTimes) + logger.info("Average process time: {}".format(averageProcessTime)) + self.captureSize=globals.ADDON.setSettingString("averageProcessTime","{}".format(averageProcessTime)) + def onPlayBackPaused(self): @@ -142,7 +147,7 @@ def _ambiLoop(self): x = Thread(target=self._updateHueRGB,name="updateHue", args=(colors['rgb'][0],colors['rgb'][1],colors['rgb'][2],L,self.transitionTime,colors['bri'])) x.daemon = True x.start() - self.monitor.waitForAbort(self.updateInterval) #seconds + self.monitor.waitForAbort(self.updateInterval) #seconds except Exception as ex: diff --git a/script.service.hue/resources/lib/ImageProcess.py b/script.service.hue/resources/lib/ImageProcess.py index 40b66c01..3d658679 100644 --- a/script.service.hue/resources/lib/ImageProcess.py +++ b/script.service.hue/resources/lib/ImageProcess.py @@ -11,6 +11,13 @@ from PIL import ImageEnhance from globals import timer +#=============================================================================== +# import os +# import xbmc +# import time +#=============================================================================== + + class ImageProcess(object): ''' classdocs @@ -35,13 +42,22 @@ def img_avg(self,img,minBri,maxBri,saturation): g = 1 b = 1 + if saturation > 1.0: + sat_converter = ImageEnhance.Color(img) + img = sat_converter.enhance(saturation) + + #======================================================================= + # clock=time.localtime() + # savepath = os.path.join(xbmc.translatePath("special://userdata/addon_data/script.service.hue/debugimages/"), str(clock) + ".png") + # img.save(savepath) + #======================================================================= + + # Create list of pixels pixels = list(img.getdata()) - if saturation > 1.0: - sat_converter = ImageEnhance.Color(img) - img = sat_converter.enhance(saturation) + for red, green, blue, alpha in pixels: # Don't count pixels that are too dark diff --git a/script.service.hue/resources/lib/globals.py b/script.service.hue/resources/lib/globals.py index 4927183e..3ccc3edd 100644 --- a/script.service.hue/resources/lib/globals.py +++ b/script.service.hue/resources/lib/globals.py @@ -3,6 +3,7 @@ import time from logging import getLogger +from collections import deque import xbmc,xbmcaddon @@ -40,10 +41,13 @@ video_enableMusicVideo = True video_enableOther = True +lastMediaType=0 + startTime = "" endTime = "" +processTimes = deque(maxlen=100) +averageProcessTime = 0 -lastMediaType=0 def timer(func): """Logs the runtime of the decorated function""" @@ -53,6 +57,7 @@ def wrapper_timer(*args, **kwargs): value = func(*args, **kwargs) endTime = time.time() # 2 runTime = endTime - startTime # 3 + processTimes.append(runTime) if performanceLogging: logger.debug("[{}] Completed in {:02.0f}ms".format(func.__name__,runTime*1000)) return value diff --git a/script.service.hue/resources/lib/kodiHue.py b/script.service.hue/resources/lib/kodiHue.py index c4e1ddd9..d4333dc6 100644 --- a/script.service.hue/resources/lib/kodiHue.py +++ b/script.service.hue/resources/lib/kodiHue.py @@ -1,5 +1,6 @@ from logging import getLogger from socket import getfqdn +from collections import deque import datetime import xbmc @@ -13,8 +14,6 @@ from . import globals from .language import get_string as _ - - logger = getLogger(globals.ADDONID) @@ -482,13 +481,22 @@ def convertTime(time): def notification(header, message, time=5000, icon=globals.ADDON.getAddonInfo('icon'), sound=True): xbmcgui.Dialog().notification(header, message, icon, time, sound) +def perfAverage(processTimes): + processTimes=list(processTimes) #deque is mutating during iteration for some reason, so copy to list. + size=len(processTimes) + total = 0 + for x in processTimes: + total += x + averageProcessTime=int(total/size * 1000) + return "{} ms".format(averageProcessTime) + class HueMonitor(xbmc.Monitor): def __init__(self): super(xbmc.Monitor,self).__init__() def onSettingsChanged(self): - logger.debug("Settings changed") + logger.info("Settings changed") #self.waitForAbort(1) loadSettings() globals.settingsChanged = True diff --git a/script.service.hue/resources/settings.xml b/script.service.hue/resources/settings.xml index 01df697d..bec14587 100644 --- a/script.service.hue/resources/settings.xml +++ b/script.service.hue/resources/settings.xml @@ -91,7 +91,9 @@ - + + + @@ -113,10 +115,10 @@ - + - - + + From 9201c44cd2a4763af7258826f379c1228b077d00 Mon Sep 17 00:00:00 2001 From: Snapcase Date: Fri, 11 Oct 2019 11:20:21 -0400 Subject: [PATCH 2/8] update strings --- script.service.hue/addon.xml | 2 +- .../resources/language/resource.language.en_GB/strings.po | 4 ++++ script.service.hue/resources/settings.xml | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/script.service.hue/addon.xml b/script.service.hue/addon.xml index 392b2004..b6d98c43 100644 --- a/script.service.hue/addon.xml +++ b/script.service.hue/addon.xml @@ -1,4 +1,4 @@ - + diff --git a/script.service.hue/resources/language/resource.language.en_GB/strings.po b/script.service.hue/resources/language/resource.language.en_GB/strings.po index 5f0416bb..90d77182 100644 --- a/script.service.hue/resources/language/resource.language.en_GB/strings.po +++ b/script.service.hue/resources/language/resource.language.en_GB/strings.po @@ -455,6 +455,10 @@ msgctxt "#30812" msgid "Disable connection message" msgstr "Disable connection message" +msgctxt "#30813" +msgid "Average image processing time:" +msgstr "Average image processing time:" + msgctxt "#30069" msgid "Recommended minimum update interval: 100ms" diff --git a/script.service.hue/resources/settings.xml b/script.service.hue/resources/settings.xml index bec14587..cc2d041a 100644 --- a/script.service.hue/resources/settings.xml +++ b/script.service.hue/resources/settings.xml @@ -92,7 +92,7 @@ - + From 123929f3656c3a58b93d94f9b84096acaefcadf4 Mon Sep 17 00:00:00 2001 From: Snapcase Date: Fri, 11 Oct 2019 11:27:29 -0400 Subject: [PATCH 3/8] update documentation --- README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 8ef07999..ae828e25 100644 --- a/README.md +++ b/README.md @@ -40,19 +40,19 @@ These settings can impact performance, and may need to be tuned for your set up. ### Basic Settings: - **Select Lights:** Only Hue bulbs and lamps that support colours (Gamuts A, B and C) can be used with this system. Lights that can only reproduce whites or color temperatures are ignored. -- **Force on :** Force the selected lights on when playback starts. Otherwise, lights will stay turned off. +- **Force on :** Force the selected lights on when playback starts. Otherwise, lights will stay turned off. +- **Minimum & Maximum Brightness:** Sets the brightness +- **Saturation:** Increase the colour saturation factor, with 1 being no change. This can create more colourful effects, but may cause incorrect colours with some content. - -### Ambilight Performance: +### Performance: Hue has a total limit of 20 commands per second which can be used by all applications and switches. Issuing too many Hue commands can cause your lights to lag or ignore input. Every selected light increases the number of necessary commands therefore influences how often lights can be updated. For more information on Hue system performance, refer to the [Hue documentation](https://developers.meethue.com/develop/application-design-guidance/hue-system-performance/). -- **Number of colours:** CPU impact. The number of colours generated from one frame. With several lights, this will produce a variety of colours. Setting this higher than your number of lights will waste CPU time generating colours that can't be displayed. + - **Update interval:** CPU and Hue impact. The minimum amount of time to wait before updating the lights, in milliseconds. 100ms will update the lights 10 times per second, 500ms, twice per second. - **Hue transition time:** Hue impact. The amount of time the lights will take to fade from one colour to the next, in milliseconds. Set to 0 for instant transition. 100ms is recommended for a quick and smooth. Hue will wait for this transition to complete before applying the next command. Normally should be the same as the update interval. - **Capture size:** CPU impact. Size at which frames are captured, in pixels of X by X. Colour calculation time is too slow with full sized frames, so they are resized first. May affect colour precision as some pixels are lost in the resize process. - -Performance logging can be enabled in the advanced setting to check the speed of the colour algorithm and Hue updates. However, these logs are very verbose and should be normally be disabled. +- **Average image processing time:** Shows the average time it took to process the colours before updating the Hue bulbs, in milliseconds. This value is updated whenever a video is stopped. ### Problems? From 2228b5f25edf440e4e16298430c7859973166fe1 Mon Sep 17 00:00:00 2001 From: Snapcase Date: Fri, 11 Oct 2019 12:57:09 -0400 Subject: [PATCH 4/8] Change saturation value to float --- script.service.hue/addon.xml | 7 +++++-- script.service.hue/resources/lib/AmbiGroup.py | 2 +- script.service.hue/resources/settings.xml | 2 +- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/script.service.hue/addon.xml b/script.service.hue/addon.xml index b6d98c43..b2e3fc52 100644 --- a/script.service.hue/addon.xml +++ b/script.service.hue/addon.xml @@ -1,4 +1,4 @@ - + @@ -22,7 +22,10 @@ Automate Hue lights with Kodi playback Automate your Philips Hue lights with Kodi. Create multi-room scenes that run when you Play, Pause or Stop media playback. Create and delete multi-room scenes from add-on settings then select which to apply for different Playback events. Can use Hue's sunrise and sunset times to automatically disable the service during daytime and turn on the lights at sunset during playback. Includes experimental Ambilight support. Check forum for more information. Automate Hue lights with Kodi playback - v0.9.0: + v0.9.5: +- Include performance information in settings window +- Fix saturation option and related settings +v0.9.0: - New ambilight algorithm (based on http://www.screenbloom.com/) - Changing settings while video playing will no longer stop ambilight v0.8.2: diff --git a/script.service.hue/resources/lib/AmbiGroup.py b/script.service.hue/resources/lib/AmbiGroup.py index 1a221d90..b9398856 100644 --- a/script.service.hue/resources/lib/AmbiGroup.py +++ b/script.service.hue/resources/lib/AmbiGroup.py @@ -71,7 +71,7 @@ def loadSettings(self): self.minBri=globals.ADDON.getSettingInt("group{}_MinBrightness".format(self.kgroupID))*255/100#convert percentage to value 1-254 self.maxBri=globals.ADDON.getSettingInt("group{}_MaxBrightness".format(self.kgroupID))*255/100#convert percentage to value 1-254 - self.saturation=globals.ADDON.getSettingInt("group{}_Saturation".format(self.kgroupID)) + self.saturation=globals.ADDON.getSettingNumber("group{}_Saturation".format(self.kgroupID)) self.captureSize=globals.ADDON.getSettingInt("group{}_CaptureSize".format(self.kgroupID)) diff --git a/script.service.hue/resources/settings.xml b/script.service.hue/resources/settings.xml index cc2d041a..0fea5b6a 100644 --- a/script.service.hue/resources/settings.xml +++ b/script.service.hue/resources/settings.xml @@ -86,7 +86,7 @@ - + From e55e1f95c8bf07dd777b5531428ee2e61d8926c9 Mon Sep 17 00:00:00 2001 From: Snapcase Date: Fri, 11 Oct 2019 14:16:57 -0400 Subject: [PATCH 5/8] Catch race condition crashes on stop --- script.service.hue/addon.xml | 2 +- script.service.hue/resources/lib/AmbiGroup.py | 10 ++++++++-- script.service.hue/resources/lib/KodiGroup.py | 9 ++++++--- 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/script.service.hue/addon.xml b/script.service.hue/addon.xml index b2e3fc52..ce4fa2af 100644 --- a/script.service.hue/addon.xml +++ b/script.service.hue/addon.xml @@ -1,4 +1,4 @@ - + diff --git a/script.service.hue/resources/lib/AmbiGroup.py b/script.service.hue/resources/lib/AmbiGroup.py index b9398856..a1dd8315 100644 --- a/script.service.hue/resources/lib/AmbiGroup.py +++ b/script.service.hue/resources/lib/AmbiGroup.py @@ -172,9 +172,12 @@ def _updateHueRGB(self,r,g,b,light,transitionTime,bri): try: self.bridge.lights[light].state(xy=xy,bri=bri,transitiontime=transitionTime) + self.ambiLights[light].update(prevxy=xy) except QhueException as ex: logger.exception("Ambi: Hue call fail") - self.ambiLights[light].update(prevxy=xy) + except KeyError: + logger.exception("Ambi: KeyError") + def _updateHueXY(self,xy,light,transitionTime): @@ -186,7 +189,10 @@ def _updateHueXY(self,xy,light,transitionTime): #if distance > self.minimumDistance: try: self.bridge.lights[light].state(xy=xy,transitiontime=transitionTime) + self.ambiLights[light].update(prevxy=xy) except QhueException as ex: logger.exception("Ambi: Hue call fail") + except KeyError: + logger.exception("Ambi: KeyError") - self.ambiLights[light].update(prevxy=xy) + diff --git a/script.service.hue/resources/lib/KodiGroup.py b/script.service.hue/resources/lib/KodiGroup.py index 7ab4d0ed..cf747a85 100644 --- a/script.service.hue/resources/lib/KodiGroup.py +++ b/script.service.hue/resources/lib/KodiGroup.py @@ -88,12 +88,15 @@ def onPlayBackStopped(self): logger.info("In KodiGroup[{}], onPlaybackStopped() , mediaType: {}, lastMediaType: {} ".format(self.kgroupID,self.mediaType,globals.lastMediaType)) self.state = STATE_STOPPED - if self.mediaType == VIDEO and not self.checkVideoActivation(self.videoInfoTag):#If video group, check video activation. Otherwise it's audio so ignore this and check other conditions. - return + try: + if self.mediaType == VIDEO and not self.checkVideoActivation(self.videoInfoTag):#If video group, check video activation. Otherwise it's audio so ignore this and check other conditions. + return + except AttributeError: + logger.error("No videoInfoTag") if self.enabled and self.checkActiveTime() and self.stopBehavior and self.mediaType == globals.lastMediaType: try: - xbmc.sleep(500) #sleep for any left over ambilight calls to complete first. + xbmc.sleep(100) #sleep for any left over ambilight calls to complete first. self.groupResource.action(scene=self.stopScene) logger.info("In KodiGroup[{}], onPlaybackStop() Stop scene activated") except QhueException as e: From 4015936b966308a86542d081f93e942fda88e1e8 Mon Sep 17 00:00:00 2001 From: Snapcase Date: Fri, 11 Oct 2019 15:50:41 -0400 Subject: [PATCH 6/8] move averageProcessTime calculation --- script.service.hue/addon.xml | 2 +- script.service.hue/resources/lib/AmbiGroup.py | 7 +++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/script.service.hue/addon.xml b/script.service.hue/addon.xml index ce4fa2af..4d3015d9 100644 --- a/script.service.hue/addon.xml +++ b/script.service.hue/addon.xml @@ -1,4 +1,4 @@ - + diff --git a/script.service.hue/resources/lib/AmbiGroup.py b/script.service.hue/resources/lib/AmbiGroup.py index a1dd8315..aac7391c 100644 --- a/script.service.hue/resources/lib/AmbiGroup.py +++ b/script.service.hue/resources/lib/AmbiGroup.py @@ -48,10 +48,6 @@ def onPlayBackStopped(self): logger.info("In ambiGroup[{}], onPlaybackStopped()".format(self.kgroupID)) self.state = STATE_STOPPED self.ambiRunning.clear() - averageProcessTime=kodiHue.perfAverage(globals.processTimes) - logger.info("Average process time: {}".format(averageProcessTime)) - self.captureSize=globals.ADDON.setSettingString("averageProcessTime","{}".format(averageProcessTime)) - def onPlayBackPaused(self): @@ -148,6 +144,9 @@ def _ambiLoop(self): x.daemon = True x.start() self.monitor.waitForAbort(self.updateInterval) #seconds + averageProcessTime=kodiHue.perfAverage(globals.processTimes) + logger.info("Average process time: {}".format(averageProcessTime)) + self.captureSize=globals.ADDON.setSettingString("averageProcessTime","{}".format(averageProcessTime)) except Exception as ex: From 9cd72dfb90cb72703d5ee7010b2d6644b95849aa Mon Sep 17 00:00:00 2001 From: Snapcase Date: Fri, 11 Oct 2019 15:59:13 -0400 Subject: [PATCH 7/8] bump version --- script.service.hue/addon.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/script.service.hue/addon.xml b/script.service.hue/addon.xml index 4d3015d9..0f5cc853 100644 --- a/script.service.hue/addon.xml +++ b/script.service.hue/addon.xml @@ -1,4 +1,4 @@ - + From 10a2cc3fe2d8a617e09a882667c65ce29d54f8b0 Mon Sep 17 00:00:00 2001 From: Snapcase Date: Fri, 11 Oct 2019 15:59:59 -0400 Subject: [PATCH 8/8] fix newline --- script.service.hue/resources/lib/AmbiGroup.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/script.service.hue/resources/lib/AmbiGroup.py b/script.service.hue/resources/lib/AmbiGroup.py index aac7391c..e6124d7d 100644 --- a/script.service.hue/resources/lib/AmbiGroup.py +++ b/script.service.hue/resources/lib/AmbiGroup.py @@ -193,5 +193,4 @@ def _updateHueXY(self,xy,light,transitionTime): logger.exception("Ambi: Hue call fail") except KeyError: logger.exception("Ambi: KeyError") - - + \ No newline at end of file