rxv icon indicating copy to clipboard operation
rxv copied to clipboard

net_radio almost works on RX-A2010 on 0.7.0rc2

Open slyoldfox opened this issue 4 years ago • 5 comments

@wuub After your changes for #58 I went ahead and tried 0.7.0rc2 on my RX-A2010

It failed with some errors, I'm not an expert in python so I can't really send a PR but I'm sure I have enough info for you to fix it quickly. This was the main error after executing

rx.net_radio('My Stations>Favourites>MNM')
Traceback (most recent call last):
  File "test.py", line 3, in <module>
    rx.net_radio('My Stations>Favourites>MNM')
  File "/usr/local/lib/python3.8/site-packages/rxv/rxv.py", line 865, in net_radio
    self.menu_reset()
  File "/usr/local/lib/python3.8/site-packages/rxv/rxv.py", line 708, in menu_reset
    while self.menu_status().layer > 1:
  File "/usr/local/lib/python3.8/site-packages/rxv/rxv.py", line 608, in menu_status
    ready = (next(res.iter("Menu_Status")).text == "Ready")
StopIteration

The call for

<NET_RADIO><List_Info>GetParam</List_Info></NET_RADIO>

responds on this system with:

<YAMAHA_AV rsp="GET" RC="0"><NET_RADIO><List_Info><Menu_Layer>2</Menu_Layer><Menu_Name>Radiobrowser</Menu_Name><Current_List><Line_1><Txt>Genres</Txt><Attribute>Container</Attribute></Line_1><Line_2><Txt>Countries</Txt><Attribute>Container</Attribute></Line_2><Line_3><Txt>Languages</Txt><Attribute>Container</Attribute></Line_3><Line_4><Txt>Most Popular</Txt><Attribute>Container</Attribute></Line_4><Line_5><Txt></Txt><Attribute>Unselectable</Attribute></Line_5><Line_6><Txt></Txt><Attribute>Unselectable</Attribute></Line_6><Line_7><Txt></Txt><Attribute>Unselectable</Attribute></Line_7><Line_8><Txt></Txt><Attribute>Unselectable</Attribute></Line_8></Current_List><Cursor_Position><Current_Line>1</Current_Line><Max_Line>4</Max_Line></Cursor_Position></List_Info></NET_RADIO></YAMAHA_AV>

In this receiver, there is no Menu_Status. I hacked it on my local install by doing - not sure if we can do something smarter there to set it to "not_available" or something (see later)

ready = 1

Inside the loop I did sleep as well (since there is no ready) state, maybe we can only sleep if "not_available" is set ?

868             if menu.ready:
869                 time.sleep(1)
870                 for line, value in menu.current_list.items():

This went a little further, until the CURSOR_RETURN which does not seem to exist here.

I changed CURSOR_RETURN to "Back" and that seems to work.

CURSOR_RETURN = "Back"

So with these 3 changes it should also work on RX-A20** models I suppose. If you need some desc.xml posted, just let me know, glad to assist!

slyoldfox avatar Feb 01 '21 19:02 slyoldfox

@slyoldfox having the portion of the desc.xml that relates to the net radio feature would be helpful.

Look for the part that contains YNC_Tag="NET_RADIO", then find the very next occurrence of Menu Func="Cursor". This lists the valid commands for the net radio feature.

Example: https://github.com/wuub/rxv/blob/da90b758da6e1cd5082bd8931f183662e54b1903/tests/samples/rx-v675-desc.xml#L1859-L1865

esev avatar Feb 03 '21 00:02 esev

This should give you all you need:

    <Menu Func="Source_Device" YNC_Tag="NET_RADIO">
        <Menu Func="Status" Title_1="Device">
            <Get>
                <Cmd ID="G3">Feature_Availability=Param_1</Cmd>
                <Param_1>
                    <Direct Func="Status_Ready">Ready</Direct>
                    <Direct Func="Status_Not Connected" Title_1="Not Ready">Not Connected</Direct>
                </Param_1>
            </Get>
        </Menu>
        <Menu Func="Play_Control" Title_1="Play Control">
            <Menu Func="Playback" Title_1="Play">
                <Put_1 ID="P1" Func="Play">Play</Put_1>
                <Put_1 ID="P1" Func="Stop">Stop</Put_1>
                <Get>
                    <Cmd ID="G1">Playback_Info=Param_1</Cmd>
                    <Param_1>
                        <Direct Func="Play">Play</Direct>
                        <Direct Func="Stop">Stop</Direct>
                    </Param_1>
                </Get>
            </Menu>
            <Menu Func="Preset" Title_1="Preset" List_Type="Slider">
                <Put_2>
                    <Cmd ID="P6">Param_1</Cmd>
                    <Param_1>
                        <Indirect ID="G4"/>
                    </Param_1>
                </Put_2>
            </Menu>
        </Menu>
        <Menu Func="Play_Info" List_Type="With_Pic" Title_1="Play Info.">
            <Menu Func="Station" Title_1="Station">
                <Get>
                    <Cmd ID="G1">Meta_Info,Station=Param_1</Cmd>
                    <Param_1>
                        <Text>0,128,UTF-8</Text>
                    </Param_1>
                </Get>
            </Menu>
            <Menu Func="Status" Title_1="Device">
                <Get>
                    <Cmd ID="G1">Feature_Availability=Param_1</Cmd>
                    <Param_1>
                        <Direct Func="Status_Ready">Ready</Direct>
                        <Direct Func="Status_Not_Connected" Title_1="Not Ready">Not Connected</Direct>
                    </Param_1>
                </Get>
            </Menu>
            <Menu Func="Playback" Title_1="Status">
                <Get>
                    <Cmd ID="G1">Playback_Info=Param_1</Cmd>
                    <Param_1>
                        <Direct Func="Play">Play</Direct>
                        <Direct Func="Stop">Stop</Direct>
                    </Param_1>
                </Get>
            </Menu>
            <Menu Func="Album_ART_URL" Title_1="AlbumART URL">
                <Get>
                    <Cmd ID="G1">Album_ART,URL=Param_1</Cmd>
                    <Param_1>
                        <Text>0,128,UTF-8</Text>
                    </Param_1>
                </Get>
            </Menu>
            <Menu Func="Album_ART_ID" Title_1="AlbumART ID">
                <Get>
                    <Cmd ID="G1">Album_ART,ID=Param_1</Cmd>
                    <Param_1>
                        <Range>0,255,1</Range>
                    </Param_1>
                </Get>
            </Menu>
            <Menu Func="Album_ART_Format" Title_1="AlbumART Format">
                <Get>
                    <Cmd ID="G1">Album_ART,Format=Param_1</Cmd>
                    <Param_1>
                        <Direct Func="BMP">BMP</Direct>
                        <Direct Func="YMF">YMF</Direct>
                    </Param_1>
                </Get>
            </Menu>
        </Menu>
        <Menu Func="List_Browse" Title_1="List Browse">
            <Menu Func="List_Control" Title_1="List Control">
                <Menu Func="Direct_Sel" Title_1="Direct Cursor Select">
                    <Put_2>
                        <Cmd ID="P2">Param_1</Cmd>
                        <Param_1>
                            <Range>1,8,1,Line_%</Range>
                        </Param_1>
                    </Put_2>
                </Menu>
                <Menu Func="Cursor" List_Type="Cursor" Title_1="Cursor">
                    <Put_1 ID="P4" Func="Cursor_Up">Up</Put_1>
                    <Put_1 ID="P4" Func="Cursor_Down">Down</Put_1>
                    <Put_1 ID="P4" Func="Cursor_Left">Back</Put_1>
                    <Put_1 ID="P4" Func="Cursor_Sel">Sel</Put_1>
                    <Put_1 ID="P4" Func="Cursor_Home">Back to Home</Put_1>
                </Menu>
                <Menu Func="Jump_Line" Title_1="Jump Page">
                    <Put_2>
                        <Cmd ID="P3">Param_1</Cmd>
                        <Param_1>
                            <Range>1,65536,1</Range>
                        </Param_1>
                    </Put_2>
                </Menu>
                <Menu Func="Page_Up_Down" Title_1="Page">
                    <Put_1 ID="P5" Func="Page_Up_1">Up</Put_1>
                    <Put_1 ID="P5" Func="Page_Down_1">Down</Put_1>
                </Menu>
                <Menu Func="Bookmark" Title_1="Bookmark">
                    <Put_1 ID="P7" Func="Bookmark_On">On</Put_1>
                    <Put_1 ID="P7" Func="Bookmark_Off">Off</Put_1>
                </Menu>
            </Menu>
            <Menu Func="List_Info" Title_1="List Info.">
                <Menu Func="Menu_Layer" Title_1="Menu Layer">
                    <Get>
                        <Cmd ID="G2">Menu_Layer=Param_1</Cmd>
                        <Param_1>
                            <Range>1,16,1</Range>
                        </Param_1>
                    </Get>
                </Menu>
                <Menu Func="Menu_Name" Title_1="Menu Name">
                    <Get>
                        <Cmd ID="G2">Menu_Name=Param_1</Cmd>
                        <Param_1>
                            <Text>0,128,UTF-8</Text>
                        </Param_1>
                    </Get>
                </Menu>
                <Menu Func="Menu_List" Title_1="Menu List">
                    <Menu Func="Menu_Line" Title_1="Line 1">
                        <Put_1 ID="P2">Line_1</Put_1>
                        <Get>
                            <Cmd Type="Container" ID="G2">Current_List,Line_1,Txt=Param_1:Current_List,Line_1,Attribute=Param_2</Cmd>
                            <Param_1 Func="Menu_Txt">
                                <Text>0,128,UTF-8</Text>
                            </Param_1>
                            <Param_2 Func="Menu_Type">
                                <Direct Func="Menu_Next">Container</Direct>
                                <Direct Func="Menu_Stay">Unplayable Item</Direct>
                                <Direct Func="Menu_Play">Item</Direct>
                                <Direct Func="Menu_Prohibit">Unselectable</Direct>
                            </Param_2>
                        </Get>
                    </Menu>
                    <Menu Func="Menu_Line" Title_1="Line 2">
                        <Put_1 ID="P2">Line_2</Put_1>
                        <Get>
                            <Cmd Type="Container" ID="G2">Current_List,Line_2,Txt=Param_1:Current_List,Line_2,Attribute=Param_2</Cmd>
                            <Param_1 Func="Menu_Txt">
                                <Text>0,128,UTF-8</Text>
                            </Param_1>
                            <Param_2 Func="Menu_Type">
                                <Direct Func="Menu_Next">Container</Direct>
                                <Direct Func="Menu_Stay">Unplayable Item</Direct>
                                <Direct Func="Menu_Play">Item</Direct>
                                <Direct Func="Menu_Prohibit">Unselectable</Direct>
                            </Param_2>
                        </Get>
                    </Menu>
                    <Menu Func="Menu_Line" Title_1="Line 3">
                        <Put_1 ID="P2">Line_3</Put_1>
                        <Get>
                            <Cmd Type="Container" ID="G2">Current_List,Line_3,Txt=Param_1:Current_List,Line_3,Attribute=Param_2</Cmd>
                            <Param_1 Func="Menu_Txt">
                                <Text>0,128,UTF-8</Text>
                            </Param_1>
                            <Param_2 Func="Menu_Type">
                                <Direct Func="Menu_Next">Container</Direct>
                                <Direct Func="Menu_Stay">Unplayable Item</Direct>
                                <Direct Func="Menu_Play">Item</Direct>
                                <Direct Func="Menu_Prohibit">Unselectable</Direct>
                            </Param_2>
                        </Get>
                    </Menu>
                    <Menu Func="Menu_Line" Title_1="Line 4">
                        <Put_1 ID="P2">Line_4</Put_1>
                        <Get>
                            <Cmd Type="Container" ID="G2">Current_List,Line_4,Txt=Param_1:Current_List,Line_4,Attribute=Param_2</Cmd>
                            <Param_1 Func="Menu_Txt">
                                <Text>0,128,UTF-8</Text>
                            </Param_1>
                            <Param_2 Func="Menu_Type">
                                <Direct Func="Menu_Next">Container</Direct>
                                <Direct Func="Menu_Stay">Unplayable Item</Direct>
                                <Direct Func="Menu_Play">Item</Direct>
                                <Direct Func="Menu_Prohibit">Unselectable</Direct>
                            </Param_2>
                        </Get>
                    </Menu>
                    <Menu Func="Menu_Line" Title_1="Line 5">
                        <Put_1 ID="P2">Line_5</Put_1>
                        <Get>
                            <Cmd Type="Container" ID="G2">Current_List,Line_5,Txt=Param_1:Current_List,Line_5,Attribute=Param_2</Cmd>
                            <Param_1 Func="Menu_Txt">
                                <Text>0,128,UTF-8</Text>
                            </Param_1>
                            <Param_2 Func="Menu_Type">
                                <Direct Func="Menu_Next">Container</Direct>
                                <Direct Func="Menu_Stay">Unplayable Item</Direct>
                                <Direct Func="Menu_Play">Item</Direct>
                                <Direct Func="Menu_Prohibit">Unselectable</Direct>
                            </Param_2>
                        </Get>
                    </Menu>
                    <Menu Func="Menu_Line" Title_1="Line 6">
                        <Put_1 ID="P2">Line_6</Put_1>
                        <Get>
                            <Cmd Type="Container" ID="G2">Current_List,Line_6,Txt=Param_1:Current_List,Line_6,Attribute=Param_2</Cmd>
                            <Param_1 Func="Menu_Txt">
                                <Text>0,128,UTF-8</Text>
                            </Param_1>
                            <Param_2 Func="Menu_Type">
                                <Direct Func="Menu_Next">Container</Direct>
                                <Direct Func="Menu_Stay">Unplayable Item</Direct>
                                <Direct Func="Menu_Play">Item</Direct>
                                <Direct Func="Menu_Prohibit">Unselectable</Direct>
                            </Param_2>
                        </Get>
                    </Menu>
                    <Menu Func="Menu_Line" Title_1="Line 7">
                        <Put_1 ID="P2">Line_7</Put_1>
                        <Get>
                            <Cmd Type="Container" ID="G2">Current_List,Line_7,Txt=Param_1:Current_List,Line_7,Attribute=Param_2</Cmd>
                            <Param_1 Func="Menu_Txt">
                                <Text>0,128,UTF-8</Text>
                            </Param_1>
                            <Param_2 Func="Menu_Type">
                                <Direct Func="Menu_Next">Container</Direct>
                                <Direct Func="Menu_Stay">Unplayable Item</Direct>
                                <Direct Func="Menu_Play">Item</Direct>
                                <Direct Func="Menu_Prohibit">Unselectable</Direct>
                            </Param_2>
                        </Get>
                    </Menu>
                    <Menu Func="Menu_Line" Title_1="Line 8">
                        <Put_1 ID="P2">Line_8</Put_1>
                        <Get>
                            <Cmd Type="Container" ID="G2">Current_List,Line_8,Txt=Param_1:Current_List,Line_8,Attribute=Param_2</Cmd>
                            <Param_1 Func="Menu_Txt">
                                <Text>0,128,UTF-8</Text>
                            </Param_1>
                            <Param_2 Func="Menu_Type">
                                <Direct Func="Menu_Next">Container</Direct>
                                <Direct Func="Menu_Stay">Unplayable Item</Direct>
                                <Direct Func="Menu_Play">Item</Direct>
                                <Direct Func="Menu_Prohibit">Unselectable</Direct>
                            </Param_2>
                        </Get>
                    </Menu>
                </Menu>
                <Menu Func="Current_Line" Title_1="Cursor Line">
                    <Get>
                        <Cmd ID="G2">Cursor_Position,Current_Line=Param_1</Cmd>
                        <Param_1>
                            <Range>1,65536,1</Range>
                        </Param_1>
                    </Get>
                </Menu>
                <Menu Func="Max_Line" Title_1="Max. Line">
                    <Get>
                        <Cmd ID="G2">Cursor_Position,Max_Line=Param_1</Cmd>
                        <Param_1>
                            <Range>0,65536,1</Range>
                        </Param_1>
                    </Get>
                </Menu>
            </Menu>
        </Menu>
        <FKey Title="Title_1">
            <Path>"Play Info."</Path>
            <F3 Title_1="Preset">"Play Control","Preset"</F3>
        </FKey>
        <FKey Title="Title_1">
            <Path>"List Browse"</Path>
            <F3 Title_1="Play Info.">"Play Info."</F3>
        </FKey>
        <FKey Title="Title_1">
            <Path/>
            <F3 Title_1="Play Info.">"Play Info."</F3>
        </FKey>
        <SKey Title="Title_1">
            <Path/>
            <Play>
                <Put_1 ID="P1">Play</Put_1>
            </Play>
            <Stop>
                <Put_1 ID="P1">Stop</Put_1>
            </Stop>
        </SKey>
        <Top Title="Title_1">"List Browse"</Top>
        <Cmd_List>
            <Define ID="P1">NET_RADIO,Play_Control,Playback</Define>
            <Define ID="P2">NET_RADIO,List_Control,Direct_Sel</Define>
            <Define ID="P3">NET_RADIO,List_Control,Jump_Line</Define>
            <Define ID="P4">NET_RADIO,List_Control,Cursor</Define>
            <Define ID="P5">NET_RADIO,List_Control,Page</Define>
            <Define ID="P6">NET_RADIO,Play_Control,Preset,Preset_Sel</Define>
            <Define ID="P7">NET_RADIO,List_Control,Bookmark</Define>
            <Define ID="G1">NET_RADIO,Play_Info</Define>
            <Define ID="G2">NET_RADIO,List_Info</Define>
            <Define ID="G3">NET_RADIO,Config</Define>
            <Define ID="G4">NET_RADIO,Play_Control,Preset,Preset_Sel_Item</Define>
        </Cmd_List>
    </Menu>

basically:

                <Menu Func="Cursor" List_Type="Cursor" Title_1="Cursor">
                    <Put_1 ID="P4" Func="Cursor_Up">Up</Put_1>
                    <Put_1 ID="P4" Func="Cursor_Down">Down</Put_1>
                    <Put_1 ID="P4" Func="Cursor_Left">Back</Put_1>
                    <Put_1 ID="P4" Func="Cursor_Sel">Sel</Put_1>
                    <Put_1 ID="P4" Func="Cursor_Home">Back to Home</Put_1>
                </Menu>

slyoldfox avatar Feb 03 '21 13:02 slyoldfox

I've been trying to use Home Assistant to change my "NET RADIO" station, but I appear to be experiencing this issue as well. The error in the HA logs is:

sk_wakeup()]>, <Future at 0x...StopIteration>) at /usr/local/
lib/python3.10/asyncio/futures.py:379 
Traceback (most recent call last): 
  File "/usr/local/lib/python3.10/asyncio/events.py", line 80, in _run 
    self._context.run(self._callback, *self._args) 
  File "/usr/local/lib/python3.10/asyncio/futures.py", line 381, in _set_state 
    _copy_future_state(other, future) 
  File "/usr/local/lib/python3.10/asyncio/futures.py", line 357, in _copy_future_state 
    dest.set_exception(_convert_future_exc(exception)) 
TypeError: StopIteration interacts badly with generators and cannot be raised into a Future 
2023-01-16 10:05:50.461 WARNING (MainThread) [homeassistant.components.media_player] Updating yamaha medi
a_player took longer than the scheduled update interval 0:00:10 

Is this the same issue, and is there a fix possible or coming? Thanks.

lindsaymarkward avatar Jan 16 '23 00:01 lindsaymarkward

@lindsaymarkward I have revisited this today to make it work with my Home Assistant installation 2023.6.2 and RX-A2010

I have tried to make it as painless as possible to patch the existing HA installation (since new releases for this library probably won't happen anytime). Personally I am running HA Core so depending if you are using HA inside Docker you might need to (re)apply this when your container is recreated.

I have pushed a v0.7.0 on my repository https://github.com/slyoldfox/rxv/releases/tag/v0.7.0. On my HA Core installation I can now install it with:

$ source homeassistant/bin/activate # Drop myself in the virtual-env 
$ pip3 -v install git+https://github.com/slyoldfox/[email protected]

I created the v0.7.0 tag (which is two commits ahead) so that pip3 install generates the correct version.py otherwise HA overwrites it during startup (because it would generate a random version.py)

Hopefully this works for you!

slyoldfox avatar Jun 24 '23 11:06 slyoldfox

Thanks! I'll give it a try when I get some time, hopefully soon. 👍

lindsaymarkward avatar Jul 12 '23 23:07 lindsaymarkward