LinkPlay Integration

Ok, done that and now there is no error when checking configuration.

But there is something in the logs:

Log Details (ERROR)
Logger: homeassistant.helpers.entity
Source: custom_components/linkplay/media_player.py:1086
First occurred: June 27, 2020, 11:52:41 PM (111 occurrences)
Last logged: 12:01:54 AM

Update for media_player.streamboxalbastru fails
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 279, in async_update_ha_state
    await self.async_device_update()
  File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 472, in async_device_update
    await self.hass.async_add_executor_job(self.update)
  File "/usr/local/lib/python3.7/concurrent/futures/thread.py", line 57, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/config/custom_components/linkplay/media_player.py", line 1086, in update
    if player_status['uri'] != "":
KeyError: 'uri'

I remember I had the same error in the past: https://community.home-assistant.io/t/linkplay-integration/33878/26

What model is your player?
What app do you use to control from Android?

From the Android app, start playing a web radio (from vtuner).
While playing, visit the following status pages:
http://your.player.ip.address/httpapi.asp?command=getStatus
http://your.player.ip.address/httpapi.asp?command=getPlayerStatus
And post the results here to see what’s wrong.

The speaker is a Promate Streambox-L https://uae.souq.com/ae-en/promate-true-wireless-speaker-powerful-bluetooth-speaker-with-wifi-streaming-and-digital-internet-radio-built-in-mic-sd-card-slot-usb-input-and-aux-input-for-smartphones-tablets-mp3-and-mp4-streambox-l-blk-blu-22046599/i/

On the electronics inside it is written LinkPlay A31 https://fccid.io/2AAPP-A31/User-Manual/15-A31-UserMan-pdf-3034717

It can be controlled using https://github.com/AndersFluur/IEastMediaRoom

The app on Android is Audio Pro.

Made some modifications on media_player.py and it`s working good. Commented lines 1086, 1091 and 1092.
Metadata seems is not working.

getStatus:

{ "language": "en_us", "ssid": "StreamBoxAlb", "hideSSID": "0", "firmware": "3.5.4522", "build": "release", "project": "StreamBoxL", "priv_prj": "StreamBoxL", "Release": "20170622", "group": "0", "expired": "0", "internet": "1", "uuid": "FF31F00673311706E1F5A00C", "MAC": "00-22-6C-60-FD-FC", "date": "2020:06:28", "time": "10:11:02", "netstat": "2", "essid": "4169724E6574", "apcli0": "192.168.0.152", "eth2": "0.0.0.0", "hardware": "A31", "VersionUpdate": "0", "NewVer": "0", "mcu_ver": "120", "disable_mcu": "0", "mcu_ver_new": "0", "ra0": "10.10.10.254", "temp_uuid": "7460BC27C9808586", "cap1": "0x104200", "capability": "0x8002000", "languages": "0x6", "streams_all": "0x7ffffffe", "streams": "0x7ffffffe", "region": "unknown", "external": "0x0", "preset_key": "6", "plm_support": "0x0", "WifiChannel": "1", "RSSI": "-61", "battery": "0", "battery_percent": "0", "securemode": "0", "upnp_version": "1001", "uart_pass_port": "8899", "communication_port": "8819", "web_firmware_update_hide": "0", "user1": "303:524", "user2": "5160:6291", "DeviceName": "StreamBoxAlb", "GroupName": "StreamBoxAlb" }

getPlayerStatus:

{"type":"0","ch":"0","mode":"10","loop":"0","eq":"0","status":"play","curpos":"875005","totlen":"0","Title":"4142432052656C6178","Artist":"54756E65496E","Album":"","alarmflag":"0","plicount":"1","plicurr":"1","vol":"37","mute":"0"}

The reason for your errors is that the firmware on your unit is very old (v3.5.4522 from 2107.06). It is missing functionality required for metadata retrieval etc.

Try installing the app named 4STREAM from play store, and trigger a check for firmware update from there. Current 2020 versions are already at 4.2.8+…

Meanwhile i’ll try to add exceptions to the code to provide an error-less experience for older firmwares.

Could not trigger a firmware update. There is no option for this in 4STREAM.

Checked http://s000.linkplay.com:8020/wifi_audio_image_7688/ for an update by UUID, but there is nothing new for my UUID (FF31F006).
Are there any other sources for firmware upgrade? Could not find on Goole.

Try with:
/httpapi.asp?command=getMvRemoteUpdateStartCheck
Then
/httpapi.asp?command=getMvRemoteUpdateStart
Then
/httpapi.asp?command=getMvRemoteUpdateStatus

No luck :frowning:
/httpapi.asp?command=getMvRemoteUpdateStartCheck = OK
/httpapi.asp?command=getMvRemoteUpdateStart = OK, but the speaker said upgrade failed
/httpapi.asp?command=getMvRemoteUpdateStatus = 50 every time I checked.

50 means indeed no new version.
You’re out of luck, then…

I made some changes to handle the missing uri from the firmware status. You might still see the metadata, as long as you started playback from Home Assistant, not from the app. Make sure you use a webradio which really pushes metadata, add this to the sources section of your config:
'http://streaming308.radionomy.com/rocks-of-ages': 'Rock of Ages'
(although their metadata doesn’t seem to be in sync with the songs but that’s their issue)

Edit: or maybe this, just fixed code to accept metadata from Shoutcast too:
'http://live2.radio-impuls.ro:80/': 'Impuls',

Great improvments! Metadata is working from HA :slight_smile:

Made some more tests and name: and device_name: seems to do nothing.
One of my speakers is named StreamBoxAlbastru in the app and Bucatarie in HA, and no matter what name I set for HA, it always shows StreamBoxAlbastru. I also deleted the device_name: line from config and still shows StreamBoxAlbastru in HA.

Yes that part is still work in progress. Currently the nane in the app and in HA have to be the same, otherwise multiroom functionality will not work.

Implementing standard multiroom in progress, to be compatible with custom:mini-media-player:

Great!
Would it be available for old firmwares like mine?

Well you’ll have to test and see - because I don’t have units with old firmwares thus I’m not aware what other problems they would have.
One issue I could think of is that maybe the old firmware doesn’t support router mode for multiroom logic.
Do you have multiple Linkplay units? All of them have old firmwares? You could help me testing.
If you can put them in a multiroom config using the app, you should run these commands on each, and post back the results here:
/httpapi.asp?command=getStatus
/httpapi.asp?command=getStatusEx
/httpapi.asp?command=getPlayerStatus
/httpapi.asp?command=multiroom:getSlaveList

You can count on me for testing!
I have 2 identical units using same firmware.
Multiroom is working from app and was working from HA using scripts.
Will run those commands when I arrive home.

Made some more tests last night and the pause button is not working quite correct. It pauses the playback, but the status remains “playing” and the button does not change the icon to paused. Same situation is when pressing on mute button…it mutes the speaker, but the icon does not change.

There’s a new multiroom system implemented in Linkplay, I really wonder if it works with older firmware. Based on the results you send for the above commands, I’ll send you new ones to test router mode for multiroom.

  • Master:
getStatus
 { "language": "en_us", "ssid": "StreamBoxAlbastru", "hideSSID": "0", "firmware": "3.5.4522", "build": "release", "project": "StreamBoxL", "priv_prj": "StreamBoxL", "Release": "20170622", "group": "0", "expired": "0", "internet": "1", "uuid": "FF31F0061C3C24A44F3E6AEC", "MAC": "00-22-6C-61-0B-4C", "date": "2020:06:30", "time": "18:57:31", "netstat": "2", "essid": "4169724E6574", "apcli0": "192.168.0.151", "eth2": "0.0.0.0", "hardware": "A31", "VersionUpdate": "0", "NewVer": "0", "mcu_ver": "120", "disable_mcu": "0", "mcu_ver_new": "0", "ra0": "10.10.10.254", "temp_uuid": "06CE953BB1444923", "cap1": "0x104200", "capability": "0x8002000", "languages": "0x0", "streams_all": "0x7ffffffe", "streams": "0x7ffffffe", "region": "unknown", "external": "0x0", "preset_key": "6", "plm_support": "0x0", "WifiChannel": "1", "RSSI": "-45", "battery": "0", "battery_percent": "0", "securemode": "0", "upnp_version": "1001", "uart_pass_port": "8899", "communication_port": "8819", "web_firmware_update_hide": "0", "user1": "323:524", "user2": "5959:6291", "DeviceName": "Bucatarie", "GroupName": "Bucatarie" }
getStatusEx
 { "language": "en_us", "ssid": "StreamBoxAlbastru", "hideSSID": "0", "firmware": "3.5.4522", "build": "release", "project": "StreamBoxL", "priv_prj": "StreamBoxL", "Release": "20170622", "group": "0", "expired": "0", "internet": "1", "uuid": "FF31F0061C3C24A44F3E6AEC", "MAC": "00-22-6C-61-0B-4C", "date": "2020:06:30", "time": "18:59:45", "netstat": "2", "essid": "4169724E6574", "apcli0": "192.168.0.151", "eth2": "0.0.0.0", "hardware": "A31", "VersionUpdate": "0", "NewVer": "0", "mcu_ver": "120", "disable_mcu": "0", "mcu_ver_new": "0", "ra0": "10.10.10.254", "temp_uuid": "06CE953BB1444923", "cap1": "0x104200", "capability": "0x8002000", "languages": "0x0", "streams_all": "0x7ffffffe", "streams": "0x7ffffffe", "region": "unknown", "external": "0x0", "preset_key": "6", "plm_support": "0x0", "WifiChannel": "1", "RSSI": "-66", "battery": "0", "battery_percent": "0", "securemode": "0", "upnp_version": "1001", "uart_pass_port": "8899", "communication_port": "8819", "web_firmware_update_hide": "0", "user1": "323:524", "user2": "5959:6291", "DeviceName": "Bucatarie", "GroupName": "Bucatarie" }
getPlayerStatus
{"type":"0","ch":"0","mode":"10","loop":"0","eq":"0","status":"play","curpos":"2444767","totlen":"0","Title":"526164696F20526F6DC3A26E69612041637475616C6974C483C5A369203130332E382028546F702034302026616D703B20506F70204D7573696329","Artist":"54756E65496E","Album":"","alarmflag":"0","plicount":"1","plicurr":"1","vol":"0","mute":"1"}
multiroom:getSlaveList
 { "slaves": 1, "slave_list": [ { "name": "Baie", "ssid": "StreamBoxAlb", "mask": 0, "volume": 16, "mute": 0, "channel": 0, "battery": 0, "ip": "10.10.10.92", "version": "3.5.4522", "uuid": "uuid:FF310001-7331-1706-E1F5-A00CFF310001" } ] }
  • Slave:
getStatus
{ "language": "en_us", "ssid": "StreamBoxAlb", "hideSSID": "0", "firmware": "3.5.4522", "build": "release", "project": "StreamBoxL", "priv_prj": "StreamBoxL", "Release": "20170622", "group": "1", "expired": "0", "internet": "1", "uuid": "FF31F00673311706E1F5A00C", "MAC": "00-22-6C-60-FD-FC", "date": "2020:06:30", "time": "19:11:13", "netstat": "2", "essid": "53747265616D426F78416C626173747275", "apcli0": "10.10.10.92", "eth2": "0.0.0.0", "hardware": "A31", "VersionUpdate": "0", "NewVer": "0", "mcu_ver": "120", "disable_mcu": "0", "mcu_ver_new": "0", "ra0": "10.10.10.254", "temp_uuid": "7460BC27C9808586", "cap1": "0x104200", "capability": "0x8002000", "languages": "0x6", "streams_all": "0x7ffffffe", "streams": "0x7ffffffe", "region": "unknown", "external": "0x0", "preset_key": "6", "plm_support": "0x0", "WifiChannel": "1", "RSSI": "-61", "battery": "0", "battery_percent": "0", "securemode": "0", "upnp_version": "1001", "uart_pass_port": "8899", "communication_port": "8819", "web_firmware_update_hide": "0", "user1": "299:524", "user2": "5160:6291", "DeviceName": "Baie", "GroupName": "Baie" }
getStatusEx
{ "language": "en_us", "ssid": "StreamBoxAlb", "hideSSID": "0", "firmware": "3.5.4522", "build": "release", "project": "StreamBoxL", "priv_prj": "StreamBoxL", "Release": "20170622", "group": "1", "expired": "0", "internet": "1", "uuid": "FF31F00673311706E1F5A00C", "MAC": "00-22-6C-60-FD-FC", "date": "2020:06:30", "time": "19:11:49", "netstat": "2", "essid": "53747265616D426F78416C626173747275", "apcli0": "10.10.10.92", "eth2": "0.0.0.0", "hardware": "A31", "VersionUpdate": "0", "NewVer": "0", "mcu_ver": "120", "disable_mcu": "0", "mcu_ver_new": "0", "ra0": "10.10.10.254", "temp_uuid": "7460BC27C9808586", "cap1": "0x104200", "capability": "0x8002000", "languages": "0x6", "streams_all": "0x7ffffffe", "streams": "0x7ffffffe", "region": "unknown", "external": "0x0", "preset_key": "6", "plm_support": "0x0", "WifiChannel": "1", "RSSI": "-63", "battery": "0", "battery_percent": "0", "securemode": "0", "upnp_version": "1001", "uart_pass_port": "8899", "communication_port": "8819", "web_firmware_update_hide": "0", "user1": "299:524", "user2": "5160:6291", "DeviceName": "Baie", "GroupName": "Baie" }
getPlayerStatus
{"type":"1","ch":"0","mode":"99","loop":"0","eq":"0","status":"play","curpos":"3458390","totlen":"-8","Title":"556E6B6E6F776E","Artist":"556E6B6E6F776E","Album":"556E6B6E6F776E","alarmflag":"0","plicount":"0","plicurr":"0","vol":"16","mute":"0"}
multiroom:getSlaveList
{ "slaves": 0 }

How were you able to access Baie while it was in slave mode? It was in a different IP addres range (10.10.10.92).

Edit: I see from the status that you have unhidden SSIDs on the speakers, I assume you connected directly to Baie’s SSID. That’s the mode I’m trying to avoid.

Anyways. Exit from multiroom mode and make sure they both are in your main subnet 192.168.0.X. Also your PC should be there too.

Run this command in your browser for Baie:
command=ConnectMasterAp:JoinGroupMaster:eth192.168.0.151:wifi0.0.0.0
(given that 192.168.0.151 is the address of Bucatarie)

Does it connect and play multiroom? Do you see multiroom appearing in the app too?

To disconnect, try with this command on any of the speakers (try with them both):
command=multiroom:Ungroup

Also run this command on both, then try again the entire procedure:
command=setMultiroomLogic:1

Do you notice any difference? For me, it connects much faster like this, than with the app’s approach. And I have devices from different manufacturers.

Made a stupid mistake. Managed to install a newer firmware from other UUID and the speaker is not working correctly. It connetcs to local wifi, but the web ui is not working correctly and can not revert to old firmware.
Do you know other methods to write the firmware?
Will spend some time trying. Hope to get it done.