Replies: 3 comments 2 replies
-
Hi, I'm testing this integration, and it seems to work fine to set the volume and select the source.
How to use this ? There is a sound mode option in HA but the names are different than those available in the Yamaha app, and the option has no effect. |
Beta Was this translation helpful? Give feedback.
-
I made some trials by editing the code, I modified the command service function as this : async def async_execute_command(self, command, notif):
"""Execute desired command against the player using factory API."""
if command.startswith('MCU'):
value = await self.async_call_linkplay_tcpuart(command)
elif command == 'Reboot':
value = await self.async_call_linkplay_httpapi("getStatus:ip:;reboot;", None)
elif command == 'PromptEnable':
value = await self.async_call_linkplay_httpapi("PromptEnable", None)
elif command == 'PromptDisable':
value = await self.async_call_linkplay_httpapi("PromptDisable", None)
elif command == 'RouterMultiroomEnable':
value = await self.async_call_linkplay_httpapi("setMultiroomLogic:1", None)
elif command == 'SetRandomWifiKey':
from random import choice
from string import ascii_letters
newkey = (''.join(choice(ascii_letters) for i in range(16)))
value = await self.async_call_linkplay_httpapi("setNetwork:1:{0}".format(newkey), None)
if value == 'OK':
value = value + ", key: " + newkey
else:
value = "key: " + newkey
elif command.startswith('SetApSSIDName:'):
ssidnam = command.replace('SetApSSIDName:', '').strip()
if ssidnam != '':
value = await self.async_call_linkplay_httpapi("setSSID:{0}".format(ssidnam), None)
if value == 'OK':
value = value + ", SoftAP SSID set to: " + ssidnam
else:
value == "SSID not specified correctly. You need 'SetApSSIDName: NewWifiName'"
elif command.startswith('WriteDeviceNameToUnit:'):
devnam = command.replace('WriteDeviceNameToUnit:', '').strip()
if devnam != '':
value = await self.async_call_linkplay_httpapi("setDeviceName:{0}".format(devnam), None)
if value == 'OK':
self._name = devnam
value = value + ", name set to: " + self._name
else:
value == "Device name not specified correctly. You need 'WriteDeviceNameToUnit: My Device Name'"
elif command == 'TimeSync':
import time
tme = time.strftime('%Y%m%d%H%M%S')
value = await self.async_call_linkplay_httpapi("timeSync:{0}".format(tme), None)
if value == 'OK':
value = value + ", time: " + tme
elif command == 'Rescan':
self._unav_throttle = False
self._first_update = True
# await self.async_schedule_update_ha_state(True)
value = "Scheduled to Rescan"
elif command == 'Update':
# await self.async_schedule_update_ha_state(True)
value = "Scheduled to Update"
else:
#value = "No such command implemented."
#_LOGGER.warning("Player %s command: %s, result: %s", self.entity_id, command, value)
try:
cmd_elements = command.split(':')
cmd = cmd_elements.pop(0).strip()
sentence = f"{cmd}"
if len(cmd_elements) != 0:
for i in range(len(cmd_elements)):
if cmd_elements[i][0] == ' ':
cmd_elements[i] = cmd_elements[i][1::]
if cmd_elements[i][-1] == ' ':
cmd_elements[i] = cmd_elements[i][0:-1]
for i in range(len(cmd_elements)):
cmd_elements[i] = cmd_elements[i].replace(' ', '%20')
sentence += ':%20{' + ':%20'.join(f'%22{e}%22' for e in cmd_elements) + '}'
jsn = None
else:
jsn = True
value = await self.async_call_linkplay_httpapi(f"{sentence}", jsn)
if notif:
self.hass.components.persistent_notification.async_create("<b>Executed command:</b><br>{0}<br><b>Result:</b><br>{1}</b><br>{2}".format(command, value, f"{sentence}"), title=self.entity_id)
except:
_LOGGER.warning("Player %s command: %s (%s) FAIL, result: %s", self.entity_id, command, f"{sentence}", value)
_LOGGER.debug("Player %s executed command: %s, result: %s", self.entity_id, command, value)
if notif:
self.hass.components.persistent_notification.async_create("<b>Executed command:</b><br>{0}<br><b>Result:</b><br>{1}".format(command, value), title=self.entity_id) So when I launch the service as follows : service: linkplay.command
data:
entity_id: media_player.yamaha_yas_109
command: "YAMAHA_DATA_GET" I get the following data in the notification :
So it seems we can call the command as is. service: linkplay.command
data:
entity_id: media_player.yamaha_yas_109
command: "YAMAHA_DATA_SET: sound program : sport" the result in the notification seems OK byt it doesn't change the sound program
What's wrong ? |
Beta Was this translation helpful? Give feedback.
-
I GOT IT !!! 💪 I need to remove the %20 (spaces) between the JSON elements. async_execute_command as following, I can change the audio mode with the command service !! service: linkplay.command
data:
entity_id: media_player.yamaha_yas_109
command: "YAMAHA_DATA_SET: sound program : sport" async def async_execute_command(self, command, notif):
"""Execute desired command against the player using factory API."""
if command.startswith('MCU'):
value = await self.async_call_linkplay_tcpuart(command)
elif command == 'Reboot':
value = await self.async_call_linkplay_httpapi("getStatus:ip:;reboot;", None)
elif command == 'PromptEnable':
value = await self.async_call_linkplay_httpapi("PromptEnable", None)
elif command == 'PromptDisable':
value = await self.async_call_linkplay_httpapi("PromptDisable", None)
elif command == 'RouterMultiroomEnable':
value = await self.async_call_linkplay_httpapi("setMultiroomLogic:1", None)
elif command == 'SetRandomWifiKey':
from random import choice
from string import ascii_letters
newkey = (''.join(choice(ascii_letters) for i in range(16)))
value = await self.async_call_linkplay_httpapi("setNetwork:1:{0}".format(newkey), None)
if value == 'OK':
value = value + ", key: " + newkey
else:
value = "key: " + newkey
elif command.startswith('SetApSSIDName:'):
ssidnam = command.replace('SetApSSIDName:', '').strip()
if ssidnam != '':
value = await self.async_call_linkplay_httpapi("setSSID:{0}".format(ssidnam), None)
if value == 'OK':
value = value + ", SoftAP SSID set to: " + ssidnam
else:
value == "SSID not specified correctly. You need 'SetApSSIDName: NewWifiName'"
elif command.startswith('WriteDeviceNameToUnit:'):
devnam = command.replace('WriteDeviceNameToUnit:', '').strip()
if devnam != '':
value = await self.async_call_linkplay_httpapi("setDeviceName:{0}".format(devnam), None)
if value == 'OK':
self._name = devnam
value = value + ", name set to: " + self._name
else:
value == "Device name not specified correctly. You need 'WriteDeviceNameToUnit: My Device Name'"
elif command == 'TimeSync':
import time
tme = time.strftime('%Y%m%d%H%M%S')
value = await self.async_call_linkplay_httpapi("timeSync:{0}".format(tme), None)
if value == 'OK':
value = value + ", time: " + tme
elif command == 'Rescan':
self._unav_throttle = False
self._first_update = True
# await self.async_schedule_update_ha_state(True)
value = "Scheduled to Rescan"
elif command == 'Update':
# await self.async_schedule_update_ha_state(True)
value = "Scheduled to Update"
else:
#value = "No such command implemented."
#_LOGGER.warning("Player %s command: %s, result: %s", self.entity_id, command, value)
value = None
try:
cmd_elements = command.split(':')
cmd = cmd_elements.pop(0).strip()
sentence = f"{cmd}"
if len(cmd_elements) != 0:
for i in range(len(cmd_elements)):
if cmd_elements[i][0] == ' ':
cmd_elements[i] = cmd_elements[i][1::]
if cmd_elements[i][-1] == ' ':
cmd_elements[i] = cmd_elements[i][0:-1]
for i in range(len(cmd_elements)):
cmd_elements[i] = cmd_elements[i].replace(' ', '%20')
sentence += ':{' + ':'.join(f'%22{e}%22' for e in cmd_elements) + '}'
jsn = None
else:
jsn = True
value = await self.async_call_linkplay_httpapi(f"{sentence}", jsn)
if notif:
self.hass.components.persistent_notification.async_create("<b>Executed command:</b><br>{0}<br><b>Result:</b><br>{1}<br><b>Sentence:</b><br>{2}".format(command, value, f"{sentence}"), title=self.entity_id)
except:
_LOGGER.warning("Player %s command: %s (%s) FAIL, result: %s", self.entity_id, command, f"{sentence}", value)
_LOGGER.debug("Player %s executed command: %s, result: %s", self.entity_id, command, value)
if notif:
self.hass.components.persistent_notification.async_create("<b>Executed command:</b><br>{0}<br><b>Result:</b><br>{1}".format(command, value), title=self.entity_id) I'll try to make a fork and add a new service to use YAMAHA_DATA_SET correctly in a clean way, I'll do a pull request when working fine. That could help creating automations in HA with some activity based presets !! |
Beta Was this translation helpful? Give feedback.
-
The APIs listed in
api.txt
were extracted from APK. Not all APIs are available for the Yamaha soundbar.The Android app mainly uses
/YAMAHA_DATA_GET
,YAMAHA_DATA_SET
, and UPnP to control the device and retrieve statusapi.txt
Beta Was this translation helpful? Give feedback.
All reactions