Skip to content

Commit

Permalink
Merge pull request #36 from zim514/dev
Browse files Browse the repository at this point in the history
v0.9.5
  • Loading branch information
Snapcase authored Oct 11, 2019
2 parents b245ae3 + 10a2cc3 commit b800602
Show file tree
Hide file tree
Showing 9 changed files with 79 additions and 29 deletions.
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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?
Expand Down
7 changes: 5 additions & 2 deletions script.service.hue/addon.xml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<addon id="script.service.hue" name="Hue Service" provider-name="zim514" version="0.9.4">
<addon id="script.service.hue" name="Hue Service" provider-name="zim514" version="0.9.5">
<requires>
<import addon="xbmc.python" version="2.26.0" />
<import addon="script.module.requests" version="2.22.0" />
Expand All @@ -22,7 +22,10 @@
<summary lang="en_GB">Automate Hue lights with Kodi playback</summary>
<description lang="en_GB">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.</description>
<disclaimer lang="en_GB">Automate Hue lights with Kodi playback</disclaimer>
<news>v0.9.0:
<news>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:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
21 changes: 15 additions & 6 deletions script.service.hue/resources/lib/AmbiGroup.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -17,6 +16,8 @@

from .globals import logger
from .language import get_string as _
from resources.lib import kodiHue



class AmbiGroup(KodiGroup.KodiGroup):
Expand Down Expand Up @@ -66,7 +67,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))

Expand Down Expand Up @@ -142,7 +143,10 @@ 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
averageProcessTime=kodiHue.perfAverage(globals.processTimes)
logger.info("Average process time: {}".format(averageProcessTime))
self.captureSize=globals.ADDON.setSettingString("averageProcessTime","{}".format(averageProcessTime))


except Exception as ex:
Expand All @@ -167,9 +171,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):
Expand All @@ -181,7 +188,9 @@ 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")

self.ambiLights[light].update(prevxy=xy)
except KeyError:
logger.exception("Ambi: KeyError")

22 changes: 19 additions & 3 deletions script.service.hue/resources/lib/ImageProcess.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,13 @@
from PIL import ImageEnhance
from globals import timer

#===============================================================================
# import os
# import xbmc
# import time
#===============================================================================


class ImageProcess(object):
'''
classdocs
Expand All @@ -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
Expand Down
9 changes: 6 additions & 3 deletions script.service.hue/resources/lib/KodiGroup.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
7 changes: 6 additions & 1 deletion script.service.hue/resources/lib/globals.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import time

from logging import getLogger
from collections import deque

import xbmc,xbmcaddon

Expand Down Expand Up @@ -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"""
Expand All @@ -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
Expand Down
14 changes: 11 additions & 3 deletions script.service.hue/resources/lib/kodiHue.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from logging import getLogger
from socket import getfqdn
from collections import deque
import datetime

import xbmc
Expand All @@ -13,8 +14,6 @@
from . import globals
from .language import get_string as _



logger = getLogger(globals.ADDONID)


Expand Down Expand Up @@ -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
12 changes: 7 additions & 5 deletions script.service.hue/resources/settings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -86,12 +86,14 @@
<setting id="group3_forceOn" type="bool" label="30057" default="false" visible="eq(-4,true)"/>
<setting id="group3_MinBrightness" type="slider" label="30810" range="1,1,100" default="10" option="percent" enable="true" visible="eq(-5,true)"/>
<setting id="group3_MaxBrightness" type="slider" label="30811" range="1,1,100" default="100" option="percent" enable="true" visible="eq(-6,true)"/>
<setting id="group3_Saturation" type="slider" label="30809" range="1,1,20" default="1" option="int" enable="true" visible="eq(-7,true)"/>
<setting id="group3_Saturation" type="slider" label="30809" range="1.00,0.1,5.00" default="1" option="float" enable="true" visible="eq(-7,true)"/>

<setting type="lsep" label="30522" visible="eq(-8,true)"/>
<setting id="group3_Interval" type="slider" label="30065" default="200" range="0,50,1000" option="int" visible="eq(-9,true)" />
<setting id="group3_TransitionTime" type="slider" label="30066" default="200" range="0,50,500" option="int" visible="eq(-10,true)"/>
<setting id="group3_CaptureSize" type="slider" label="30067" default="400" range="150,50,1000" option="int" visible="eq(-11,true)"/>
<setting id="group3_CaptureSize" type="slider" label="30067" default="400" range="150,50,1920" option="int" visible="eq(-11,true)"/>
<setting id="averageProcessTime" type="text" label="30813" enable="false" visible="eq(-12,true)"/>



<setting id="group3_Lights" type="text" label="30035" default="-1" enable="false" visible="false" />
Expand All @@ -113,10 +115,10 @@
<category label = "32101">
<setting id="initialFlash" type="bool" label="5110" default="False" />
<setting id="reloadFlash" type="bool" label="5111" default="False" />
<setting type="sep"/>
<setting id="disableConnectionMessage" type="bool" label="30812" default="False"/>
<setting id="separateLogFile" type="bool" label="32105" default="False"/>
<setting id="performanceLogging" type="bool" label="30068" default="False"/>
<setting id="disableConnectionMessage" type="bool" label="30812" default="False"/>
<setting id="performanceLogging" type="bool" label="30068" default="False" visible="False"/>


</category>
</settings>
Expand Down

0 comments on commit b800602

Please sign in to comment.