Mi Portable Bluetooth Speaker XMYX04WM and HAOS version 2023.9.2

There are options for connecting bluetooth devices to the Home Assistant

But since I am using HAOS version 2023.9.2, the instructions are partially not suitable, although the essence is the same. I will share my implementation of connecting Mi Portable Bluetooth Speaker XMYX04WM to HAOS

You do not need to install anything in HAOS version 2023.9.2, just use what is already in HAOS. It is done through the SSH addon terminal

Do the column pairing first as written in this documentation

Pairing
Using bluetoothctl
Begin by starting bluetoothctl and follow these basic steps:

$ bluetoothctl

The prompt should display:

[bluetooth]#
List the available controllers:

[bluetooth]# list
Display information about a controller:

[bluetooth]# show controller_mac_address
Set the default controller:

[bluetooth]# select controller_mac_address
Power on the controller:

[bluetooth]# power on
Enable the agent and set it as default:

[bluetooth]# agent on
[bluetooth]# default-agent
Set the controller as discoverable (temporarily for 3 minutes) and pairable:

[bluetooth]# discoverable on
[bluetooth]# pairable on
Scan for devices:

[bluetooth]# scan on
Put the device into pairing mode. This generally involves pressing a button or a combinations of buttons, usually for several seconds.

Discover the device MAC address:

[bluetooth]# devices
Pair with the device:

[bluetooth]# pair device_mac_address
Enter the PIN if prompted:

[agent] PIN code: ####
Trust the device:

[bluetooth]# #trust device_mac_address
Connect to the device:

[bluetooth]# connect device_mac_address
Display information about the device:

[bluetooth]# info device_mac_address
The device is now paired:

[bluetooth]# quit

The Mi Portable Bluetooth Speaker XMYX04WM knows how to transmit battery level and you can see that, and you can also see the states of the speaker, which I use in my variant as sensors and controls

image

Output detailed information about the device with the command, where XX:XX:XX:XX:XX:XX is your mac address of the device

bluetoothctl info XX:XX:XX:XX:XX:XX

If you don’t see Battery Percentage in the row, you need to enable an experimental feature that will report the battery level of your device. Read more about it here

You can pre-install the nano package with the command if it is not installed

apk add nano

Open the main.conf file at the path /etc/bluetooth/main.conf

nano /etc/bluetooth/main.conf

And add a line at the very top

Experimental=true

This is what it should look like

[General]

Experimental=true

Save the changes in the main.conf file and exit

Run the command again and see if the string Battery Percentage appears.

bluetoothctl info XX:XX:XX:XX:XX:XX

Next, create sensors and switch, where XX:XX:XX:XX:XX:XX is your mac address of the device. Before creating sensors, you can check whether the commands output yes or no answers and battery level.

#Command line Sensor https://www.home-assistant.io/integrations/sensor.command_line
command_line:
  - sensor:
      name: Mi Portable Bluetooth Speaker Battery Level
      unique_id: mi portable bluetooth speaker battery level
      command: bluetoothctl info XX:XX:XX:XX:XX:XX | grep "Battery Percentage" | cut -d ' ' -f4 | sed 's/^.//;s/.$//'
      scan_interval: 10
      device_class: battery

  - binary_sensor:
      name: Mi Portable Bluetooth Speaker Power
      unique_id: mi portable bluetooth speaker power
      command: l2ping -c 1 XX:XX:XX:XX:XX:XX > /dev/null 2>&1 && echo yes || echo no
      scan_interval: 5
      payload_on: "yes"
      payload_off: "no"

  - binary_sensor:
      name: Mi Portable Bluetooth Speaker Connected
      unique_id: mi portable bluetooth speaker connected
      command: bluetoothctl info XX:XX:XX:XX:XX:XX | grep "Connected" | cut -d ' ' -f2
      scan_interval: 10
      device_class: connectivity
      payload_on: "yes"
      payload_off: "no"

  - binary_sensor:
      name: Mi Portable Bluetooth Speaker Paired
      unique_id: mi portable bluetooth speaker paired
      command: bluetoothctl info XX:XX:XX:XX:XX:XX | grep "Paired" | cut -d ' ' -f2
      scan_interval: 10
      payload_on: "yes"
      payload_off: "no"

  - binary_sensor:
      name: Mi Portable Bluetooth Speaker Bonded
      unique_id: mi portable bluetooth speaker bonded
      command: bluetoothctl info XX:XX:XX:XX:XX:XX | grep "Bonded" | cut -d ' ' -f2
      scan_interval: 10
      payload_on: "yes"
      payload_off: "no"

  - binary_sensor:
      name: Mi Portable Bluetooth Speaker Trusted
      unique_id: mi portable bluetooth speaker trusted
      command: bluetoothctl info XX:XX:XX:XX:XX:XX | grep "Trusted" | cut -d ' ' -f2
      scan_interval: 10
      payload_on: "yes"
      payload_off: "no"

  - binary_sensor:
      name: Mi Portable Bluetooth Speaker Blocked
      unique_id: mi portable bluetooth speaker blocked
      command: bluetoothctl info XX:XX:XX:XX:XX:XX | grep "Blocked" | cut -d ' ' -f2
      scan_interval: 10
      payload_on: "yes"
      payload_off: "no"

  - switch:
      name: Mi Portable Bluetooth Speaker Connection
      unique_id: mi portable bluetooth speaker connection
      scan_interval: 10
      command_on: bluetoothctl connect XX:XX:XX:XX:XX:XX
      command_off: bluetoothctl disconnect XX:XX:XX:XX:XX:XX
      command_state: bluetoothctl info XX:XX:XX:XX:XX:XX | grep "Connected" | cut -d ' ' -f2
      value_template: '{{ value == "yes" }}'
      icon: >
        {% if value == "yes" %} mdi:bluetooth-connect
        {% else %} mdi:bluetooth-off
        {% endif %}


#Template https://www.home-assistant.io/integrations/template/
template:
  - sensor:
      - name: 'Mi Portable Bluetooth Speaker'
        unique_id: mi portable bluetooth speaker
        state: '{{ states("binary_sensor.mi_portable_bluetooth_speaker_power") }}'
        icon: >
          {% if is_state("binary_sensor.mi_portable_bluetooth_speaker_power", "on") %}
            mdi:bluetooth
          {% else %}
            mdi:bluetooth-off
          {% endif %}
        attributes:
          Battery: '{{ states("sensor.mi_portable_bluetooth_speaker_battery_level") }}'
          Connected: '{{ states("binary_sensor.mi_portable_bluetooth_speaker_connected") }}'
          Paired: '{{ states("binary_sensor.mi_portable_bluetooth_speaker_paired") }}'
          Bonded: '{{ states("binary_sensor.mi_portable_bluetooth_speaker_bonded") }}'
          Trusted: '{{ states("binary_sensor.mi_portable_bluetooth_speaker_trusted") }}'
          Blocked: '{{ states("binary_sensor.mi_portable_bluetooth_speaker_blocked") }}'

#This is to hide or display the player card. This is used in the card condition
#input_boolean:
  mi_portable_bluetooth_speaker_control_panel_1:
    name: "Mi Portable Bluetooth Speaker Control Panel 1"
    icon: mdi:menu

To output sound to the speaker, install the MPD addon

In the Home Assistant add-on store, manually add the following repository URL

https://github.com/Poeschl/Hassio-Addons

Next, read the description in the documentation about creating your own custom mpd.conf file


image

Open the mpd.conf file at /share/mpd/mpd.conf and add the following

music_directory			"/media/Music" #Путь к музыке любой
playlist_directory		"/media/Playlists" #Путь к плейлисту любой
db_file				"/data/database/mpd.db" #Не меняем путь


#In the name line, enter a device name that you understand
#In the sink line specify the mac address of your device. Replace XX_XX_XX_XX_XX_XX with your #device's mac address
audio_output {
	type "pulse"
	name "Pulse Mi Portable Bluetooth Speaker"
	sink "bluez_sink.XX_XX_XX_XX_XX_XX.a2dp_sink"
}

В configuration.yaml добавляем

media_player:
  - platform: mpd
    name: "MPD Mi Portable Bluetooth Speaker"
    host: localhost
    port: 6600

Create a card where all the information is displayed, and also make a hiding media card, it can appear after turning on the column or manually. Here it is at your discretion

image
image
image
image

Card code

type: vertical-stack
cards:
  - type: vertical-stack
    cards:
      - type: entities
        entities:
          - entity: sensor.mi_portable_bluetooth_speaker
            name: Mi Bluetooth Speaker
            type: custom:multiple-entity-row
            show_state: false
            secondary_info:
              attribute: Battery
              name: 'Battery:'
            entities:
              - entity: switch.mi_portable_bluetooth_speaker_connection
                name: Connected
                icon: mdi:bluetooth-connect
                state_color: true
                type: button
                tap_action:
                  action: toggle
                styles:
                  height: 60px
                  width: 60px
              - entity: binary_sensor.mi_portable_bluetooth_speaker_power
                name: Power
                icon: mdi:bluetooth
                state_color: true
                styles:
                  height: 60px
                  width: 60px
              - entity: input_boolean.mi_portable_bluetooth_speaker_control_panel_1
                name: Media
                icon: mdi:music
                state_color: true
                type: button
                tap_action:
                  action: toggle
                styles:
                  height: 60px
                  width: 60px
      - type: conditional
        conditions:
          - entity: binary_sensor.mi_portable_bluetooth_speaker_power
            state: 'on'
          - entity: input_boolean.mi_portable_bluetooth_speaker_control_panel_1
            state: 'on'
        card:
          type: custom:mushroom-media-player-card
          entity: media_player.mpd_mi_portable_bluetooth_speaker
          fill_container: false
          use_media_info: false
          show_volume_level: false
          volume_controls:
            - volume_set
          media_controls:
            - play_pause_stop
            - next
            - previous
            - on_off
          layout: vertical
          collapsible_controls: false

Текст на русском (Text in Russian )

Есть варианты подключения bluetooth девайсов к Home Assistant

Но так как я использую HAOS version 2023.9.2, то инструкции частично не подходят, хотя суть одинаковая. Я поделюсь своей реализацией подключения Mi Portable Bluetooth Speaker XMYX04WM к HAOS

Устанавливать в HAOS version 2023.9.2 ничего не нужно, просто будем использовать то, что и так заложено в HAOS. Делается через терминал аддона SSH

Сделайте сначала спаривание колонки как написано в этой документации

Pairing
Using bluetoothctl
Begin by starting bluetoothctl and follow these basic steps:

$ bluetoothctl

The prompt should display:

[bluetooth]#
List the available controllers:

[bluetooth]# list
Display information about a controller:

[bluetooth]# show controller_mac_address
Set the default controller:

[bluetooth]# select controller_mac_address
Power on the controller:

[bluetooth]# power on
Enable the agent and set it as default:

[bluetooth]# agent on
[bluetooth]# default-agent
Set the controller as discoverable (temporarily for 3 minutes) and pairable:

[bluetooth]# discoverable on
[bluetooth]# pairable on
Scan for devices:

[bluetooth]# scan on
Put the device into pairing mode. This generally involves pressing a button or a combinations of buttons, usually for several seconds.

Discover the device MAC address:

[bluetooth]# devices
Pair with the device:

[bluetooth]# pair device_mac_address
Enter the PIN if prompted:

[agent] PIN code: ####
Trust the device:

[bluetooth]# #trust device_mac_address
Connect to the device:

[bluetooth]# connect device_mac_address
Display information about the device:

[bluetooth]# info device_mac_address
The device is now paired:

[bluetooth]# quit

Колонка Mi Portable Bluetooth Speaker XMYX04WM умеет передавать уровень заряда аккумулятора и это можно увидеть, а также можно увидеть состояния колонки, которые я использую в своем варианте в качестве сенсоров и управления

image

Выводим детальную информацию об устройстве командой, где XX:XX:XX:XX:XX:XX это ваш мак адрес устройства

bluetoothctl info XX:XX:XX:XX:XX:XX

Если в строке не увидели Battery Percentage, то нужно включить экспериментальную функцию, которая будет сообщать об уровне заряда батареи устройства. Подробнее об этом читаем здесь

Предварительно можете установить пакет nano командой, если он не установлен

apk add nano

Откроем файл main.conf по пути /etc/bluetooth/main.conf

nano /etc/bluetooth/main.conf

И добавим в самый вверх строчку

Experimental=true

Вот так должно выглядеть

[General]

Experimental=true

Сохраняем изменения в файлике main.conf и выходим

Повторно проверяем запускаем команду и смотрим, появилась ли строка Battery Percentage

bluetoothctl info XX:XX:XX:XX:XX:XX

Дальше создаем сенсоры и выключатель, где XX:XX:XX:XX:XX:XX это ваш мак адрес устройства. Перед созданием сенсоров, предварительно можете проверить, выводят ли команды ответы да или нет и уровень заряда батареи

#Command line Sensor https://www.home-assistant.io/integrations/sensor.command_line
command_line:
  - sensor:
      name: Mi Portable Bluetooth Speaker Battery Level
      unique_id: mi portable bluetooth speaker battery level
      command: bluetoothctl info XX:XX:XX:XX:XX:XX | grep "Battery Percentage" | cut -d ' ' -f4 | sed 's/^.//;s/.$//'
      scan_interval: 10
      device_class: battery

  - binary_sensor:
      name: Mi Portable Bluetooth Speaker Power
      unique_id: mi portable bluetooth speaker power
      command: l2ping -c 1 XX:XX:XX:XX:XX:XX > /dev/null 2>&1 && echo yes || echo no
      scan_interval: 5
      payload_on: "yes"
      payload_off: "no"

  - binary_sensor:
      name: Mi Portable Bluetooth Speaker Connected
      unique_id: mi portable bluetooth speaker connected
      command: bluetoothctl info XX:XX:XX:XX:XX:XX | grep "Connected" | cut -d ' ' -f2
      scan_interval: 10
      device_class: connectivity
      payload_on: "yes"
      payload_off: "no"

  - binary_sensor:
      name: Mi Portable Bluetooth Speaker Paired
      unique_id: mi portable bluetooth speaker paired
      command: bluetoothctl info XX:XX:XX:XX:XX:XX | grep "Paired" | cut -d ' ' -f2
      scan_interval: 10
      payload_on: "yes"
      payload_off: "no"

  - binary_sensor:
      name: Mi Portable Bluetooth Speaker Bonded
      unique_id: mi portable bluetooth speaker bonded
      command: bluetoothctl info XX:XX:XX:XX:XX:XX | grep "Bonded" | cut -d ' ' -f2
      scan_interval: 10
      payload_on: "yes"
      payload_off: "no"

  - binary_sensor:
      name: Mi Portable Bluetooth Speaker Trusted
      unique_id: mi portable bluetooth speaker trusted
      command: bluetoothctl info XX:XX:XX:XX:XX:XX | grep "Trusted" | cut -d ' ' -f2
      scan_interval: 10
      payload_on: "yes"
      payload_off: "no"

  - binary_sensor:
      name: Mi Portable Bluetooth Speaker Blocked
      unique_id: mi portable bluetooth speaker blocked
      command: bluetoothctl info XX:XX:XX:XX:XX:XX | grep "Blocked" | cut -d ' ' -f2
      scan_interval: 10
      payload_on: "yes"
      payload_off: "no"

  - switch:
      name: Mi Portable Bluetooth Speaker Connection
      unique_id: mi portable bluetooth speaker connection
      scan_interval: 10
      command_on: bluetoothctl connect XX:XX:XX:XX:XX:XX
      command_off: bluetoothctl disconnect XX:XX:XX:XX:XX:XX
      command_state: bluetoothctl info XX:XX:XX:XX:XX:XX | grep "Connected" | cut -d ' ' -f2
      value_template: '{{ value == "yes" }}'
      icon: >
        {% if value == "yes" %} mdi:bluetooth-connect
        {% else %} mdi:bluetooth-off
        {% endif %}


#Template https://www.home-assistant.io/integrations/template/
template:
  - sensor:
      - name: 'Mi Portable Bluetooth Speaker'
        unique_id: mi portable bluetooth speaker
        state: '{{ states("binary_sensor.mi_portable_bluetooth_speaker_power") }}'
        icon: >
          {% if is_state("binary_sensor.mi_portable_bluetooth_speaker_power", "on") %}
            mdi:bluetooth
          {% else %}
            mdi:bluetooth-off
          {% endif %}
        attributes:
          Battery: '{{ states("sensor.mi_portable_bluetooth_speaker_battery_level") }}'
          Connected: '{{ states("binary_sensor.mi_portable_bluetooth_speaker_connected") }}'
          Paired: '{{ states("binary_sensor.mi_portable_bluetooth_speaker_paired") }}'
          Bonded: '{{ states("binary_sensor.mi_portable_bluetooth_speaker_bonded") }}'
          Trusted: '{{ states("binary_sensor.mi_portable_bluetooth_speaker_trusted") }}'
          Blocked: '{{ states("binary_sensor.mi_portable_bluetooth_speaker_blocked") }}'

#Это нужно для того, чтобы скрыть или отобразить карточку плеера. Это используется в #карточке условие
input_boolean:
  mi_portable_bluetooth_speaker_control_panel_1:
    name: "Mi Portable Bluetooth Speaker Control Panel 1"
    icon: mdi:menu

Для вывода звука на колонку устанавливаем аддон MPD

В магазин дополнений Home Assistant вручную добавьте следующий URL-адрес репозитория

https://github.com/Poeschl/Hassio-Addons

Далее читаем описание в документации о создании своего пользовательского файла mpd.conf


image

Открываем файлик mpd.conf по пути /share/mpd/mpd.conf и добавляем следующее

music_directory			"/media/Music" #Путь к музыке любой
playlist_directory		"/media/Playlists" #Путь к плейлисту любой
db_file				"/data/database/mpd.db" #Не меняем путь


#Тут указываем
#В строке name укажите понятное вам имя устройства
#В строке sink указываем мак адрес вашего девайса. Замените XX_XX_XX_XX_XX_XX на свой #мак адрес устройства
audio_output {
	type "pulse"
	name "Pulse Mi Portable Bluetooth Speaker"
	sink "bluez_sink.XX_XX_XX_XX_XX_XX.a2dp_sink"
}

В configuration.yaml добавляем

media_player:
  - platform: mpd
    name: "MPD Mi Portable Bluetooth Speaker"
    host: localhost
    port: 6600

Создаем карточку, где выводится вся информация, а также делаем скрывающуюся медиа карточку, она может появляться после включения колонки или вручную. Тут на ваше усмотрение

image
image
image
image

Код карточки

type: vertical-stack
cards:
  - type: vertical-stack
    cards:
      - type: entities
        entities:
          - entity: sensor.mi_portable_bluetooth_speaker
            name: Mi Bluetooth Speaker
            type: custom:multiple-entity-row
            show_state: false
            secondary_info:
              attribute: Battery
              name: 'Battery:'
            entities:
              - entity: switch.mi_portable_bluetooth_speaker_connection
                name: Connected
                icon: mdi:bluetooth-connect
                state_color: true
                type: button
                tap_action:
                  action: toggle
                styles:
                  height: 60px
                  width: 60px
              - entity: binary_sensor.mi_portable_bluetooth_speaker_power
                name: Power
                icon: mdi:bluetooth
                state_color: true
                styles:
                  height: 60px
                  width: 60px
              - entity: input_boolean.mi_portable_bluetooth_speaker_control_panel_1
                name: Media
                icon: mdi:music
                state_color: true
                type: button
                tap_action:
                  action: toggle
                styles:
                  height: 60px
                  width: 60px
      - type: conditional
        conditions:
          - entity: binary_sensor.mi_portable_bluetooth_speaker_power
            state: 'on'
          - entity: input_boolean.mi_portable_bluetooth_speaker_control_panel_1
            state: 'on'
        card:
          type: custom:mushroom-media-player-card
          entity: media_player.mpd_mi_portable_bluetooth_speaker
          fill_container: false
          use_media_info: false
          show_volume_level: false
          volume_controls:
            - volume_set
          media_controls:
            - play_pause_stop
            - next
            - previous
            - on_off
          layout: vertical
          collapsible_controls: false

1 Like

Thank you @DivanX10 for this comprehensive description
I have followed it and it works for me but there is a problem.
What I am trying to do is to play audio on Alexa echo dot 4 from my home assistant OS running on virtual box on my laptop through laptop built-in Bluetooth.
Right after connecting to Alexa’s Bluetooth and play audio source (from media or radio in home assistant) it works, but if I changed the radio station for example, audio outputs from my HA host machine speakers despite Bluetooth connection is still established and I have to disconnect then connect to Alexa once more

side note
When adding custom_config:
/share/mpd/mpd.conf
mpd media player stopped playing audio from any source

If your MPD has stopped playing sound through /share/mpd/mpd.conf, then you need to identify your sound card, the one that outputs sound and register it in mpd.conf. You can figure out the audio output via audio_output yourself by reading here or here. These are just examples, although the Internet is full of options for how audio_output is configured in mpd.

I pulled it out of the text at this link so that you understand where to look

Alsa
With Alsa you can send the audio output directly to your sound card. By default, this will be the device hw:0,0, which corresponds to one audio output on your sound card. A typical configuration is:

audio_output { 
       type                    "alsa"
       name                    "My ALSA Device"
       device                  "hw:0,0"     # optional
       format                  "44100:16:2" # optional
}

If you want to plug your amplifier in another hole in your sound card, you will have to figure out how to address a specific physical connection on your sound card, or if you want to make use of the digital output, please see the specialized Alsa HOWTO.

PulseAudio
PulseAudio seems to become the default sound server in more and more linux distributions. It has some advantages over Alsa, such as the capability to stream the output to a server over the network, or volume control over the sources of the audio, and the ability to flexibly put an audio stream to another sink.

To make use of PulseAudio with mpd, you just need to add a new audio_output section with the type set to “pulse”. You can also specify a server and sink parameter. A typical audio_output section looks like this:

audio_output {
      type    "pulse"
      name    "My MPD PulseAudio Output"
      #server  "localhost"   # optional
      #sink    "alsa_output" # optional
}

thank you @DivanX10 for your reply and sorry for being late.
here are screenshots of my testing.

  1. mpd.conf file config

  2. mpd addon config

  3. mpd addon log after initial start

  4. mpd addon log after playing a media

I see many errors but unfortunately, I have no experience in audio things, so I am not able to troubleshoot them.

You are informed in the logs:

The error “bind to ‘0.0.0.0:6600’ failed: Address already in use (continuing anyway, because binding to ‘[::]:6600’ succeeded)” indicates that port 6600 is already in use on your system, MPD may still be running

Unable to access files /media/Playlists: There is no such file or directory that indicates that there are no /media/Playlists and /media/Music folders.

Check the folders in the media folder. If these folders are not there, then create them
image

Check what is written in mpd.conf. It should be like this, just add your audio_output

music_directory		     "/media/Music"
playlist_directory		 "/media/Playlists"
db_file				     "/data/database/mpd.db"


audio_output {
	type "pulse"
	name "Pulse Mi Portable Bluetooth Speaker"
	sink "bluez_sink.XX_XX_XX_XX_XX_XX.a2dp_sink"
}

I have connected a second of the same speaker, how can I configure it?

Add a second speaker to the audio output. This way you can register as many columns as you like

#Adding the first column
audio_output {
	type "pulse"
	name "Pulse Mi Portable Bluetooth Speaker 1"
	sink "bluez_sink.XX_XX_XX_XX_XX_01.a2dp_sink"
}

#Adding a second column
audio_output {
	type "pulse"
	name "Pulse Mi Portable Bluetooth Speaker 2"
	sink "bluez_sink.XX_XX_XX_XX_XX_02.a2dp_sink"
}

#Add a third column
audio_output {
	type "pulse"
	name "Pulse Mi Portable Bluetooth Speaker 3"
	sink "bluez_sink.XX_XX_XX_XX_XX_03.a2dp_sink"
}

add a second column to your configuration

media_player:
#The first column is added
  - platform: mpd
    name: "MPD Mi Portable Bluetooth Speaker 1"
    host: localhost
    port: 6600

#A second column is added
  - platform: mpd
    name: "MPD Mi Portable Bluetooth Speaker 2"
    host: localhost
    port: 6600

#A third column is added
  - platform: mpd
    name: "MPD Mi Portable Bluetooth Speaker 3"
    host: localhost
    port: 6600