Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Volume up/down - steps to small with Sonos speakers #27

Closed
htvekov opened this issue Feb 13, 2020 · 23 comments
Closed

Volume up/down - steps to small with Sonos speakers #27

htvekov opened this issue Feb 13, 2020 · 23 comments
Assignees
Labels
bug Something isn't working

Comments

@htvekov
Copy link
Contributor

htvekov commented Feb 13, 2020

  • 'Single tap' on button volume up/down only changing volume on device by 0.02
    (Very slow. Need 50 'single taps' to get from zero volume to full volume).

  • When volume button (up/down) is pressed and held, volume only changes 7 or 8 'steps' (of 0.02) and then stops - Eg. from 0.16 to 0.30 (No continuous volume up/down).

Info: HA range for Sonos volume: 0.00 to 1.00 (with 2 decimals).
HA direct service call also adjust volume with same amount (0.02) as ControllerX.

AppDaemon: 4
Hass-core: 0.105.2
Device: Ikea remote E1810 / Sonos One/Play:5/Play:1 speakers. Only tested with single Sonos speakers (no groups)
Integration: z2m
Logs: None (No errors. Only slow volume adjusting 😉)

@htvekov htvekov added the bug Something isn't working label Feb 13, 2020
@xaviml
Copy link
Owner

xaviml commented Feb 13, 2020

Hi @htvekov

I released v2.2.1b1 with a fix for this bug. These are the instructions to try the code:

Through HACS

If you go to ControllerX in HACS, you can select in the menu Show Beta and install v2.2.1b1. Then you will need to restart your AppDaemon server.

Through files

You can download the dev branch and copy the controllerx folder inside apps into /config/appdaemon/apps/. Then you will need to restart your AppDaemon server.

There is a new attribute for media player controllers called "volume_steps" which is 10 by default. This value is how many steps need to be made to go from min to max. So if set to "2" and the volume is 0, it will go to 50% and with the second click to 100%.

Let me know if this fixes the issue and it works as expected :)
If you guys try it out, let me know about it. Thanks :)

@htvekov
Copy link
Contributor Author

htvekov commented Feb 14, 2020

Hi' Xavi.

Just tested the beta and volume is now working perfectly with Sonos speakers 👍😁
Volume steps at appx. 20 is in my opinion a good setting for Sonos. Not to fast and not to slow.

I must admit that I'm quite impressed with your app and your dedication to make it better and more versatile 😎

One thing that could improve your app even further, is to be able to switch between Sonos sources which are stored in Sonos app and exposed to HA (Spotify playlists, Radio stations, Pod cast etc.)
For now when your not playing a playlist, left/right button does nothing/no action on Sonos speakers.
Here's the attributes for one of my Sonos speakers with the source list exposed:
image

With service call media_player.select_source, source can be set and will be started with same call.

image

Thanks for all the work so far, Xavi. I really appreciate it !!!

Cheers
Henning

@xaviml
Copy link
Owner

xaviml commented Feb 14, 2020

Hi @htvekov,

Thanks for the feedback. I am glad that now works as expected and thanks for the appreciation.

I am currently working on making a custom controller where you will be able to set the custom call services on controller actions through the yaml configuration (#12). With this, you will be able to map any action to a service (e.g. change the source for you media player). I will keep you updated on it.

I will close this issue once I release v2.2.1.

@htvekov
Copy link
Contributor Author

htvekov commented Feb 14, 2020

Hi' Xavi.

Custom controller - I like it already !! 😎👍

@xaviml xaviml closed this as completed in ebaec3b Feb 14, 2020
@xaviml
Copy link
Owner

xaviml commented Feb 14, 2020

This issue has been fixed in v2.2.1

@xaviml
Copy link
Owner

xaviml commented Feb 18, 2020

Hi @htvekov ,

I have released v2.3.0b1 with support to custom controllers, now you can map controller events to predefined actions or HA services. Since there is no support for sources list yet on the media player controllers, you can define this with CallServiceController. This would be a configuration that let you control your media player and also adds the functionality for the source list.

office_speaker:
  module: controllerx
  class: E1810MediaPlayerController
  controller: sensor.office_controller_action
  integration: z2m
  media_player: media_player.office_speaker
  actions:
    - toggle
    - brightness_up_click
    - brightness_down_click
    - arrow_left_click
    - arrow_right_click
    - brightness_up_hold
    - brightness_up_release
    - brightness_down_hold
    - brightness_down_release
office_speaker_source_list:
  module: controllerx
  class: CallServiceController
  controller: sensor.office_controller_action
  integration: z2m
  mapping:
    arrow_left_hold:
      service: media_player.select_source
      data:
        entity_id: media_player.office_speaker
        source: DR P5 (Pop)
    arrow_right_hold:
      service: media_player.select_source
      data:
        entity_id: media_player.office_speaker
        source: DR P6 Beat

The actions attribute from the first app instance is not necessary, but ust in case in the future we are a functionality to the 2 events that are not used (arrow_left_hold and arrow_right_hold).

If you hold the arrow left it should change to DR P5 (Pop) and if you hold the right arrow it should change to DR P6 Beat. I will try to add a predefined action to change source list on every click or hold (from left to right in a circular way). But this won't be added yet.

Let me know if this works as expected. Thanks @htvekov :)

@htvekov
Copy link
Contributor Author

htvekov commented Feb 20, 2020

Hi' Xavi.

Didn't even realise (until now), that you've also written on this issue.
Do you sleep at all ? 😉

Thank you for the example 👍 I'll test in the weekend.
This is better than nothing. But you're right. I would really like to be able to 'scroll' forward and backwards in the source list. As automation this will only be possible AFAIK with heavy scripting and complex string compare commands/syntax).
Automation really are limited with more complex situations. I need variables and the possibility to store strings etc. It's quite difficult to do without, since all programming I've done since the 80's have included this. I'm 'old school' and not used to YAML syntax, Linux, Python etc. 😁But I'm not dead yet and learning every day 😉But the 'learning curve' is unfirtunately not as steep as 20 years ago.

Thank you once again, Xavi.
Really appreciated !

Regards
Henning

@xaviml
Copy link
Owner

xaviml commented Feb 20, 2020

Perfect @htvekov! Let me know if this works as expected then and if you have any problems.

I will try to implement a predefined action for the forward/backward source list, but I do no promise anything. Can you maybe let me know if source list is also available when the speaker is off or idle?

I agree with you, HA automations are limited when it comes to complex situations, but this is why solutions like python script and AppDaemon exist, which I am glad for it. If you ever need help or you have any question with Python, you can ask me :)

Regards,
Xavi M.

@htvekov
Copy link
Contributor Author

htvekov commented Feb 21, 2020

Hi' Xavi.

I'll test your sample code tomorrow.
Don't expect any problems, it's quite straighforward 😊

But it would be REALLY cool if you at some point could find the time to implement Sonos source list choice 😎😎

Just made a quick test with my Sonos speakers. When paused/idle source list is available.
And luckily source list is also available in HA, even if speaker is not available (offline completely) 😊
Source list is dynamic. If changes are made via Sonos app to 'favourites list', this will immediately reflect on states in HA for all (online) speakers.

If speaker is completely off, the change to source list will be applied when online again (as idle/paused). Didn't notice that source list was actually updated before I was using it for playing. But maybe I wasn't patient enough for states to update ?

image

Wish you a lovely weekend, Xavi 🍻🍻😁

@htvekov
Copy link
Contributor Author

htvekov commented Feb 21, 2020

Just tested, Xavi.

Test example for source list is working as expected 😊👍
Only one service call pr. mapped key allowed, or should syntax be altered ?
Right now only last service call is executed, if more than one is listed (pr. key)
I would like to short flash a light, to indicate key actually has been pressed. As it takes Sonos some 5-6 seconds to initiate new source list and play.

image

@xaviml
Copy link
Owner

xaviml commented Feb 21, 2020

Hi @htvekov

I have some good news for you, Santa came late, but it came. I have implemented the following in v2.3.0b5:

  1. Predefined action in media players: Go next and previous source.
    Now on the custom controllers you can call the actions next_source and previous_source. This is a simple example that JUST changes the source when left and right arrows are clicked.
example_app:
  module: controllerx
  class: CustomMediaPlayerController
  controller: livingroom-controller
  integration: z2m
  media_player: media_player.livingroom_speaker
  mapping:
    arrow_left_click: previous_source
    arrow_right_click: next_source

Also, I added to the E1810MediaPlayerController the next and previous source when holding arrow left and right. So just with the following configuration, you have the next and previous source:

office_controller:
  module: controllerx
  class: E1810MediaPlayerController
  controller: <sensor id>
  integration: z2m
  volume_steps: 20
  media_player: group.sonos_all
  1. Call multiple call services.
    In the previous comment you said that you wanted to call two services and unfortunately that was not implemented, but since Santa came, I have added support for multiple services as well as just one service (like before). However, when you want to state a list in yaml, you need to use the dash "-", otherwise it is parsed as a map, so your configuration should look like:
office_controller:
  module: controllerx
  class: E1810MediaPlayerController
  controller: <sensor id>
  integration: z2m
  volume_steps: 20
  media_player: group.sonos_all
  actions:
    - toggle
    - brightness_up_click
    - brightness_down_click
    #- arrow_left_click
    #- arrow_right_click
    - brightness_up_hold
    - brightness_up_release
    - brightness_down_hold
    - brightness_down_release
office_speaker_source_list:
  module: controllerx
  class: CallServiceController
  controller: <sensor id>
  integration: z2m
  mapping: 
    arrow_left_click: 
      - service: media_player.select_source
        data:
          entity_id: group.sonos_all
          source: DR P3
      - service: light.turn_on
        data:
          entity_id: light.kontor_loft
          flash: short
    arrow_right_click:
      - service: media_player.select_source
        data:
          entity_id: group.sonos_all
          source: DR P4 Fyn 96.8 (Nyheder)
      - service: light.turn_on
        data:
          entity_id: light.kontor_loft
          flash: short

One last thing, since the next and previous source is a predefined action, you cannot call a service (like turning on a light) after next and previous has been called since they are different custom controllers. However, you can turn the light at the same time as the source is changing by creating two app instances as you have done and then mapping in the same key two different actions but with different type of custom controller.

I would really appreciate it if you could test both (number 1 and 2) configurations to know that it works as expected in your end. I have implemented it and I put everything under tests, but I do not have a speaker with a source list to test. Thank you and merry Christmas 😝

Note: I have converted the image to text with an OCR online, there might be some typos. Just for future reference, you can check here how to include code in markdown. Instead of "javascript" or "python", you can put "yaml".

@htvekov
Copy link
Contributor Author

htvekov commented Feb 22, 2020

Hi' Xavi

Holy crap - My saviour in shining Python armor ! 🚀🚀😎😎
This is just fu¤&#ng great !!!! 😁

Quick test on both 1. and 2. failed. As far as i can see in error log, it hasn't read source list properly or (can't find the separator ',')

I'll write more extensively, when you've had the chance to check code.

I've changed settings to one single speaker for test, as the Sonos group obviously doesn't have the states for 'source list' or anything else for that matter.
So if Sonos groups should be controlled (most people probably use groups as they have more than one Sonos speaker), the 'master' speakers states has to be used.
Master speaker is always the first speaker in 'sonos_group' list exposed in HA.

image

Below error log for Custom Media Player controller example (1).
Similar errors thrown when using the standard E1810Mediaplayer (2)

  module: controllerx
  class: E1810MediaPlayerController
  controller: sensor.0x90fd9ffffe0cbd69_action
  integration: z2m
  volume_steps: 20
  media_player: media_player.stue
  #actions:
  #  - toggle
  #  - brightness_up_click
  #  - brightness_down_click
  #  - arrow_left_click
  #  - arrow_right_click
  #  - arrow_left_hold
  #  - arrow_right_hold
  #  - brightness_up_hold
  #  - brightness_up_release
  #  - brightness_down_hold
  #  - brightness_down_release

example_app:
  module: controllerx
  class: CustomMediaPlayerController
  controller: sensor.0x90fd9ffffe0cbd69_action
  integration: z2m
  media_player: media_player.stue
  mapping:
    arrow_left_click: previous_source
    arrow_right_click: next_source

2020-02-22 11:08:45.042278 WARNING example_app: ------------------------------------------------------------
2020-02-22 11:08:45.043983 WARNING example_app: Unexpected error in worker for App example_app:
2020-02-22 11:08:45.045561 WARNING example_app: Worker Ags: {'id': 'cfad4c00164a4364875fe49ed1d559bb', 'name': 'example_app', 'objectid': 'b6a40a0796d74bebb260d473fd7c9c69', 'type': 'state', 'function': <bound method Z2MIntegration.callback of <core.integration.z2m.Z2MIntegration object at 0x74a30c40>>, 'attribute': 'state', 'entity': 'sensor.0x90fd9ffffe0cbd69_action', 'new_state': 'arrow_right_click', 'old_state': '', 'pin_app': True, 'pin_thread': 8, 'kwargs': {'__thread_id': 'MainThread'}}
2020-02-22 11:08:45.047313 WARNING example_app: ------------------------------------------------------------
2020-02-22 11:08:45.049823 WARNING example_app: Traceback (most recent call last):
File "/usr/lib/python3.8/site-packages/appdaemon/threading.py", line 709, in async_worker
await funcref(entity, attr, old_state, new_state, self.AD.state.sanitize_state_kwargs(app, args["kwargs"]))
File "/config/appdaemon/apps/controllerx/core/integration/z2m.py", line 15, in callback
await self.controller.handle_action(new)
File "/config/appdaemon/apps/controllerx/core/controller.py", line 109, in handle_action
await action(*args)
File "/config/appdaemon/apps/controllerx/core/controller.py", line 28, in _action_impl
await method(self, *args, **kwargs)
File "/config/appdaemon/apps/controllerx/core/type/media_player_controller.py", line 43, in change_source_list
source_list = source_list.split(",")
AttributeError: 'list' object has no attribute 'split'
2020-02-22 11:08:45.051271 WARNING example_app: ------------------------------------------------------------

@xaviml
Copy link
Owner

xaviml commented Feb 22, 2020

That could be because of the attribute is already a list, I thought it would be a string, this is why I splitted. I will try to fix that or you can go to that file as you have the path and comment that line with # and see if that fixes it.

@htvekov
Copy link
Contributor Author

htvekov commented Feb 22, 2020

I'll check...

@htvekov
Copy link
Contributor Author

htvekov commented Feb 22, 2020

Yep. Commenting line 43 in media_player_controller.py did it 👍😎
All working including 'circular' (from first to last and vice versa)

Custom Media Controller and E1810 Media Controller working as expected.

Only issue is playing with Sonos Groups.
I believe that it could be solved like this:

  1. Add single media player in config file (Expected 'master' speaker)
  2. Read sonos_group entities and apply volume change to all entities in group
  3. Read source_list from first sonos_group entity

Hmm... Have to check what states are for a speaker pulled from a group and playing on its own ??

@htvekov
Copy link
Contributor Author

htvekov commented Feb 22, 2020

OK. If Sonos group is 'dissolved' (By Sonos app or via HA) then speakers sonos_group attribute remains with their 'own' entity in group

image

@htvekov
Copy link
Contributor Author

htvekov commented Feb 22, 2020

One last thing about sonos_group.
Applying source changes to any single group entity (regardless of master or slave entities) reflects on all other entities in group.

@htvekov
Copy link
Contributor Author

htvekov commented Feb 23, 2020

Hi' Xavi.

I forgot to test multiple service calls using same controller (trigger) and sharing same key mapping, but as different app instances and/or different classes.

Thought that this should work, but it don't ?
If both example_app and office_speaker_source_list are active, then light won't flash but source changes.
If example app is 'commented out' then light will flash.

Perhaps I misunderstood how multiple service calls (using different apps with identical keys) should be used ??

Regards
Henning

office_controller:
  module: controllerx
  class: E1810MediaPlayerController
  controller: sensor.0x90fd9ffffe0cbd69_action
  integration: z2m
  volume_steps: 20
  media_player: group.sonos_all
  actions:
    - toggle
    - brightness_up_click
    - brightness_down_click
  #  - arrow_left_click
  #  - arrow_right_click
  #  - arrow_left_hold
  #  - arrow_right_hold
    - brightness_up_hold
    - brightness_up_release
    - brightness_down_hold
    - brightness_down_release

example_app:
  module: controllerx
  class: CustomMediaPlayerController
  controller: sensor.0x90fd9ffffe0cbd69_action
  integration: z2m
  media_player: media_player.stue
  mapping:
    arrow_left_click: previous_source
    arrow_right_click: next_source

office_speaker_source_list:
  module: controllerx
  class: CallServiceController
  controller: sensor.0x90fd9ffffe0cbd69_action
  integration: z2m
  mapping:
    arrow_left_click:
      - service: light.turn_on
        data:
          entity_id: light.kontor_loft
          flash: short
#     - service: media_player.select_source
#       data:
#         entity_id: group.sonos_all
#         source: DR P3
    arrow_right_click:
#     - service: media_player.select_source
#       data:
#         entity_id: group.sonos_all
#         source: DR P4 Fyn 96.8 (Nyheder)
      - service: light.turn_on
        data:
          entity_id: light.kontor_loft
          flash: short

@xaviml
Copy link
Owner

xaviml commented Feb 23, 2020

Hi @htvekov,

Regarding the Sonos group, how does it behave when the Sonos are grouped with the group integration. Could you please open a new issue for it and describe what does work and what does not? Let's see if we can find a generic solution for it, I cannot read the sonos_group since that would just solve the problem to Sonos devices. Thanks :)

@xaviml
Copy link
Owner

xaviml commented Feb 23, 2020

Hi again @htvekov,

I observed the same as you (calling different actions in different app instances) and apparently that was a very nasty bug. I could fix it and I test it with a real example:

livingroom_light:
  module: controllerx
  class: E1810Controller
  controller: sensor.livingroom_controller_action
  integration: z2m
  light: light.livingroom
  smooth_power_on: true
test:
  module: controllerx
  class: CallServiceController
  controller: sensor.livingroom_controller_action
  integration: z2m
  mapping:
    toggle:
      - service: notify.telegram_test
        data:
          message: Test message 1
      - service: notify.telegram_test
        data:
          message: Test message 2

With this configuration I can press the toogle button and it does the following:

  • Toggle the light
  • Sends "Test message 1" to Telegram
  • Sends "Test message 2" to Telegram

These changes can be found in v2.3.0b6 as well as the fix for the "source_list" (Removing line 43 in media_player_controller.py).

Let me know if this fixed the problem related to calling different actions with different app instances. Sorry for all the bugs related to this, but I really appreciate it that you are finding them :)

@htvekov
Copy link
Contributor Author

htvekov commented Feb 23, 2020

Hi' Xavi.

Multiple service calls, sharing same key, now works with latest beta v2.3.0b6
Problem solved ! 👍😊

Don't worry about the bugs. I've never seen code that was flawless in first beta or beta no. #15 for that matter 😉
And as your code rapidly becomes more and more complex, bugs are bound to pop up.
I would be more worried if there was no bugs... 🐛🦟🕷🐞

@htvekov
Copy link
Contributor Author

htvekov commented Feb 23, 2020

Regarding the Sonos 'issue' the main problem AFAIK is that Sonos implementation is unique, as they (still) can't be integrated with other speakers in a multiroom setting in eg. Google Home.
So nothing generic about Sonos I'm afraid in general and in HA implementation.
Handling the Sonos 'specials' should in my opinion have been handled properly on a lower level in HA (media.player integration). But I'm not fully aware of the problems concerning Sonos integration.

My Sonos group is manually added. There's no automatic Group creation in HA and now autogenerated groups in HA are depricated all together very soon.

So my Sonos group only contains the entities:

entity_id:
  - media_player.kokken
  - media_player.kitchen
  - media_player.stue
order: 4
friendly_name: sonos_all

I'll open a new issue regarding Sonos, Xavi.
I'll try and describe what's working and what's not. Will also describe what I've observed about group behaviour and using single speakers.
And describe how I with the numerous possibilities in ControllerX can tweak my way to the desired behaviour 😁

@xaviml
Copy link
Owner

xaviml commented Feb 23, 2020

Okay, we will leave this issue closed then and discuss the Sonos group in the new issue. Thanks @htvekov

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants