Syncing LED Lights to Playing Music

That helps. I used my chromecast entity so I should be ok there.

May I ask, how do you trigger this “on and off”? My chromecast stays on indefinitely so It would be scrolling screensaver art the whole time.

I know it’s a lot of questions but this sounds really amazing and I’d love to get it working. Do you spotify through HA, or just any regular method of casting it to the chromecast?

No problem.

In my experience, HA sort of “ignores” the Chromecast screensaver art (as in - the Chromecast screensaver art is not cached on the server or assigned to the photo attribute that I use, “entity_picture”), so, my lights only change color when I’m casting something. Unfortunately, that does include things like YouTube and other casted apps, but I rarely cast anything other than Spotify so I don’t mind it.

Usually I use Spotify Connect through the Spotify app to cast to my Chromecast.

I wonder if this would work using a tv that I mainly use as a 2nd source for sports or a digital photo frame that I have a Apple TV hooked up to that uses the cloud screen saver to display pictures of my family. It would be cool to get the Hue lights to react to the pictures being displayed.

I finally got around to setting this up and it’s working great for me, super cool!

2045946869069330403

I’m not sure if it’s my LED strip or the nature of the averaging of the album cover but everything is pretty primary red-green-blue. I will have to try it with other bulbs and since if the effect is more subtle.

Is it possible to create a new sensor in appdaemon? It would be great to have the color value returned as a sensor to be used in automations instead of sending command directly to one light. I could set up a dummy template light with MQTT and use that instead I guess.

It seems this could be easily adapted for a camera entity too, I will see if I can modify your code to do that. I have a webcam that gets a view of the sunset, would be interesting to sync that to lighting.

1 Like

You haven’t started playing AppDaemon yet. Do you want to use colorthief if you don’t use AppDaemon?

@astone Am a newbie to Home assistant can you help me how to set LED strips to sync with Music.

Any tutorial links /video would help.

I currently use Flux_LED component in Home assistant but as per my exploration that doesn’t have sync music option

Please help thanks in advance.

I just came across this thread.
@astone great idea and nice app!

I have made some changes on my side:

  • Faster color extraction (using Pillow directly). On my Raspberry Pi, it is about 8x faster!
  • Extract a color palette instead, that matches the number of lights added in the config
  • An optional entity state check condition

Also, @easwaran83, if you still need help for that, I’ve made a README wich explains what I did to set this up.

The code can be found here: https://github.com/ericmatte/HomeAutomation/tree/master/appdaemon

Cheers!

2 Likes

Just came across this tread as well, and I have now added your app from Github in Appdaemon. Unfortunately I have not been able to get this working so far. This is the log from Appdaemon. Any idea of what is wrong?

[22:03:12] INFO: Starting AppDaemon...
2019-06-02 22:03:22.162682 INFO AppDaemon Version 3.0.5 starting
2019-06-02 22:03:22.163473 INFO Configuration read from: /config/appdaemon/appdaemon.yaml
2019-06-02 22:03:22.167909 INFO AppDaemon: Starting Apps
2019-06-02 22:03:22.188468 INFO AppDaemon: Loading Plugin HASS using class HassPlugin from module hassplugin
2019-06-02 22:03:23.057717 INFO AppDaemon: HASS: HASS Plugin Initializing
2019-06-02 22:03:23.059071 INFO AppDaemon: HASS: HASS Plugin initialization complete
2019-06-02 22:03:23.060468 INFO Starting Dashboards
2019-06-02 22:03:23.084990 INFO API is disabled
2019-06-02 22:03:23.109139 INFO AppDaemon: HASS: Connected to Home Assistant 0.93.2
2019-06-02 22:03:23.698777 INFO AppDaemon: Got initial state from namespace default
2019-06-02 22:03:25.210243 INFO AppDaemon: Reading config
2019-06-02 22:03:25.225741 INFO AppDaemon: /config/appdaemon/apps/apps.yaml added or modified
2019-06-02 22:03:25.226431 INFO AppDaemon: /config/appdaemon/apps/apps.yaml added or modified
2019-06-02 22:03:25.227127 INFO AppDaemon: App 'tv_lights_sync' added
2019-06-02 22:03:25.228281 INFO AppDaemon: Adding /config/appdaemon/apps to module import path
2019-06-02 22:03:25.229970 INFO AppDaemon: Loading App Module: /config/appdaemon/apps/tv_lights_sync.py
2019-06-02 22:03:25.233144 WARNING AppDaemon: ------------------------------------------------------------
2019-06-02 22:03:25.233900 WARNING AppDaemon: Unexpected error loading module: /config/appdaemon/apps/tv_lights_sync.py:
2019-06-02 22:03:25.234581 WARNING AppDaemon: ------------------------------------------------------------
2019-06-02 22:03:25.240876 WARNING AppDaemon: Traceback (most recent call last):
  File "/usr/local/lib/python3.7/site-packages/appdaemon/appdaemon.py", line 2026, in check_app_updates
    self.read_app(mod["name"], mod["reload"])
  File "/usr/local/lib/python3.7/site-packages/appdaemon/appdaemon.py", line 1809, in read_app
    self.modules[module_name] = importlib.import_module(module_name)
  File "/usr/local/lib/python3.7/importlib/__init__.py", line 127, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 1006, in _gcd_import
  File "<frozen importlib._bootstrap>", line 983, in _find_and_load
  File "<frozen importlib._bootstrap>", line 967, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 677, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 724, in exec_module
  File "<frozen importlib._bootstrap_external>", line 860, in get_code
  File "<frozen importlib._bootstrap_external>", line 791, in source_to_code
  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
  File "/config/appdaemon/apps/tv_lights_sync.py", line 7
    <!DOCTYPE html>
    ^
SyntaxError: invalid syntax
2019-06-02 22:03:25.241582 WARNING AppDaemon: ------------------------------------------------------------
2019-06-02 22:03:25.242603 WARNING AppDaemon: Removing associated apps:
2019-06-02 22:03:25.243927 WARNING AppDaemon: tv_lights_sync
2019-06-02 22:03:25.246722 INFO AppDaemon: App initialization complete
2019-06-02 22:04:45.921106 INFO AppDaemon: Reading config
2019-06-02 22:04:45.941962 INFO AppDaemon: /config/appdaemon/apps/apps.yaml added or modified
2019-06-02 22:04:45.942603 INFO AppDaemon: App 'tv_lights_sync' changed
2019-06-02 22:04:45.944269 INFO AppDaemon: Terminating tv_lights_sync
2019-06-02 22:04:45.945180 INFO AppDaemon: Initializing app tv_lights_sync using class tv_lights_sync from module tv_lights_sync
2019-06-02 22:04:45.947996 WARNING AppDaemon: ------------------------------------------------------------
2019-06-02 22:04:45.948657 WARNING AppDaemon: Unexpected error initializing app: tv_lights_sync:
2019-06-02 22:04:45.949194 WARNING AppDaemon: ------------------------------------------------------------
2019-06-02 22:04:45.950687 WARNING AppDaemon: Traceback (most recent call last):
  File "/usr/local/lib/python3.7/site-packages/appdaemon/appdaemon.py", line 2051, in check_app_updates
    self.init_object(app)
  File "/usr/local/lib/python3.7/site-packages/appdaemon/appdaemon.py", line 1567, in init_object
    modname = __import__(app_args["module"])
  File "/config/appdaemon/apps/tv_lights_sync.py", line 7
    <!DOCTYPE html>
    ^
SyntaxError: invalid syntax
2019-06-02 22:04:45.951263 WARNING AppDaemon: ------------------------------------------------------------

This is my settings in apps.yaml:
Not sure if I did the photo_attribute right.

tv_lights_sync:
  module: tv_lights_sync
  class: tv_lights_sync
  ha_url: http://hassio/homeassistant
  media_player: media_player.chromecast
  photo_attribute: '{{ states.media_player.chromecast.attributes.entity_picture }}'
  condition:
    entity: input_boolean.sync_tv_lights
    state: 'on'
  lights:
    - light.livingroom

@noidea, oh yeah, you can let the photo attribute just like it was on my file: photo_attribute: "entity_picture", so that the app will listen for changes in the “entity_picture” of your media_player.chromecast.
The <!DOCTYPE html> in your error log makes me think that urlopen(url) returned a 404 not found for the image, so that could be it.

That value should only change if you want to listen to some other type of entity where the image attribute name is different.

Let me know if it works!

For any new users like me, you’ll need to define some system packages in the AppDaemon configuration for pillow to work.
For the pillow implementation by @mate2002, you’ll need libjpeg and tiff:

{
  "disable_auto_token": false,
  "system_packages": [
    "libjpeg",
    "tiff"
  ],
  "python_packages": [
    "pillow"
  ]
}
1 Like

I just tried to get this working but get this error:

2019-10-02 15:39:32.730127 INFO AppDaemon: Initializing app tv_lights_sync using class tv_lights_sync from module tv_lights_sync
2019-10-02 15:39:42.085808 WARNING AppDaemon: ------------------------------------------------------------
2019-10-02 15:39:42.086174 WARNING AppDaemon: Unexpected error in worker for App tv_lights_sync:
2019-10-02 15:39:42.086533 WARNING AppDaemon: Worker Ags: {'name': 'tv_lights_sync', 'id': UUID('0e1167f6-9482-4470-987e-3b17b9c0c0be'), 'type': 'attr', 'function': <bound method tv_lights_sync.change_lights_color of <tv_lights_sync.tv_lights_sync object at 0x7f66f468b240>>, 'attribute': 'entity_picture', 'entity': 'media_player.kodi', 'new_state': '/api/media_player_proxy/media_player.kodi?token=049b6277be0d7e0fdca1fb1115856373eeff63a88290316e090f18af2a6b9a71&cache=882c9dfe7888a18b', 'old_state': None, 'kwargs': {'attribute': 'entity_picture', 'handle': UUID('4b5a3138-740a-4930-bdbd-bc3454359f30')}}
2019-10-02 15:39:42.086804 WARNING AppDaemon: ------------------------------------------------------------
2019-10-02 15:39:42.087597 WARNING AppDaemon: Traceback (most recent call last):
  File "/usr/lib/python3.7/site-packages/appdaemon/appdaemon.py", line 595, in worker
    self.sanitize_state_kwargs(app, args["kwargs"]))
  File "/config/appdaemon/apps/tv_lights_sync.py", line 24, in change_lights_color
    rgb_colors = self.get_colors(newUrl)
  File "/config/appdaemon/apps/tv_lights_sync.py", line 35, in get_colors
    fd = urlopen(url)
  File "/usr/lib/python3.7/urllib/request.py", line 222, in urlopen
    return opener.open(url, data, timeout)
  File "/usr/lib/python3.7/urllib/request.py", line 510, in open
    req = Request(fullurl, data)
  File "/usr/lib/python3.7/urllib/request.py", line 328, in __init__
    self.full_url = url
  File "/usr/lib/python3.7/urllib/request.py", line 354, in full_url
    self._parse()
  File "/usr/lib/python3.7/urllib/request.py", line 383, in _parse
    raise ValueError("unknown url type: %r" % self.full_url)
ValueError: unknown url type: '/api/media_player_proxy/media_player.kodi?token=049b6277be0d7e0fdca1fb1115856373eeff63a88290316e090f18af2a6b9a71&cache=882c9dfe7888a18b'

2019-10-02 15:39:42.087885 WARNING AppDaemon: ------------------------------------------------------------

This is my config:

tv_lights_sync:
  module: tv_lights_sync
  class: tv_lights_sync
  ha_url: http://192.168.1.41:8123
  media_player: media_player.kodi
  photo_attribute: "entity_picture"
  condition:
    entity: input_boolean.sync_tv_lights
    state: 'on'
  lights:
    - light.hyperion

This is my appdaemon.yaml:

log:
  logfile: STDOUT
  errorfile: STDERR
appdaemon:
  threads: 10
  app_dir: /config/appdaemon/apps
  plugins:
    HASS:
      ha_key: "hass"
      type: hass
      ha_url: http://192.168.1.41:8123
      token: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJmMzNhOTRmYTRmYTk0MzE4YThmMTlmMGM2MTc0YzA0NiIsImlhdCI6MTU2OTU5MDEyMiwiZXhwIjoxODg0OTUwMTIyfQ.7-V5EMb7ri1OZYjGNVX517uWYjkFnycla5nAJlJF4S0

I don’t use this app, but your config is wrong.

You should put quotes arount the ‘ha_url’ like this.

tv_lights_sync:
  module: tv_lights_sync
  class: tv_lights_sync
  ha_url: "http://192.168.1.41:8123"
  media_player: media_player.kodi
  photo_attribute: "entity_picture"
  condition:
    entity: input_boolean.sync_tv_lights
    state: 'on'
  lights:
    - light.hyperion

In addition i strongly advise you to use secrets. Here for example I would use one for the ha url.
You can read about it here.

https://appdaemon.readthedocs.io/en/latest/CONFIGURE.html#secrets

I have got this up and running but whenever the song changes I get this error:

2020-02-23 00:35:43.690485 WARNING music_lights: ------------------------------------------------------------
2020-02-23 00:35:43.691937 WARNING music_lights: Unexpected error in worker for App music_lights:
2020-02-23 00:35:43.693276 WARNING music_lights: Worker Ags: {'id': 'b72dbb3f476a4f1ba29553df06f027f8', 'name': 'music_lights', 'objectid': 'f9612abb240f46368e34cbf3dacda62c', 'type': 'state', 'function': <bound method music_lights.change_led_color of <music_lights.music_lights object at 0x75436cd0>>, 'attribute': 'entity_picture', 'entity': 'media_player.ted_s_bedroom_tv', 'new_state': 'https://i.scdn.co/image/ab67616d00001e027dea0aa103144aa9740835fd', 'old_state': 'https://i.scdn.co/image/ab67616d00001e02bc200956ba9de7303d8bd068', 'pin_app': True, 'pin_thread': 0, 'kwargs': {'attribute': 'entity_picture', '__thread_id': 'thread-0'}}
2020-02-23 00:35:43.694866 WARNING music_lights: ------------------------------------------------------------
2020-02-23 00:35:43.697234 WARNING music_lights: Traceback (most recent call last):
  File "/usr/lib/python3.8/site-packages/appdaemon/threading.py", line 777, in worker
    funcref(entity, attr, old_state, new_state,
  File "/config/appdaemon/apps/music_lights.py", line 20, in change_led_color
    rgb_color = self.get_color(self.args["ha_url"] + new)
  File "/config/appdaemon/apps/music_lights.py", line 24, in get_color
    fd = urlopen(url)
  File "/usr/lib/python3.8/urllib/request.py", line 222, in urlopen
    return opener.open(url, data, timeout)
  File "/usr/lib/python3.8/urllib/request.py", line 531, in open
    response = meth(req, response)
  File "/usr/lib/python3.8/urllib/request.py", line 640, in http_response
    response = self.parent.error(
  File "/usr/lib/python3.8/urllib/request.py", line 569, in error
    return self._call_chain(*args)
  File "/usr/lib/python3.8/urllib/request.py", line 502, in _call_chain
    result = func(*args)
  File "/usr/lib/python3.8/urllib/request.py", line 649, in http_error_default
    raise HTTPError(req.full_url, code, msg, hdrs, fp)
urllib.error.HTTPError: HTTP Error 401: Unauthorized
2020-02-23 00:35:43.698932 WARNING music_lights: ------------------------------------------------------------

Anyone have any ideas why it is not authorised to change the light colour?

@Tedsterh I’ve made an appdaemon app that is available in HACS and that would probably fix your issue: https://github.com/ericmatte/ad-media-lights-sync

2 Likes

@mate2002 This works perfectly, I have it working with my Lifx lights as well as my TP-Link ones, thank you!

1 Like

@mate2002 I don’t have much experience with AppDaemon but I just got your light sync app up and running. One issue I can’t seem to solve it seems to only change when the image URL changes aka a new item is playing. But I have automation setup when I pause the TV it changes the light color but when I play again it doesn’t seem to change the color back due to the URL not changing.
Any thoughts on how i can make this happen?

Hey Eric, newbie question:

I couldn’t find your add-on when trying to add it through HACS default way and also couldn’t add it as a custom repository. Am I missing something?

Thanks in advance!

Will this work with an rgb light bulb flashed with tasmota?

By the way, the RGB light just changed to a static light based on the music cover art or does it sync to the music playing?

I think it’d work with an rgb light bulb flashed with Tasmota. The RGB light just changes to a static light based on the music cover art.

1 Like

Trying to find if there’s a way to read a songs waveform into Hassio… Then use the live data to automate lights.