Closed htvekov closed 4 years ago
Hi @htvekov
I released v2.2.1b1 with a fix for this bug. These are the instructions to try the code:
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.
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 :)
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:
With service call media_player.select_source, source can be set and will be started with same call.
Thanks for all the work so far, Xavi. I really appreciate it !!!
Cheers Henning
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.
Hi' Xavi.
Custom controller - I like it already !! ๐๐
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 :)
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
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.
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 ?
Wish you a lovely weekend, Xavi ๐ป๐ป๐
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.
Hi @htvekov
I have some good news for you, Santa came late, but it came. I have implemented the following in v2.3.0b5:
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
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 :stuck_out_tongue_closed_eyes:
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".
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.
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: ------------------------------------------------------------
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.
I'll check...
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:
Hmm... Have to check what states are for a speaker pulled from a group and playing on its own ??
OK. If Sonos group is 'dissolved' (By Sonos app or via HA) then speakers sonos_group attribute remains with their 'own' entity in group
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.
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
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 :)
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:
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 :)
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... ๐๐ฆ๐ท๐
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 ๐
Okay, we will leave this issue closed then and discuss the Sonos group in the new issue. Thanks @htvekov
'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 ๐)