AirMusic Control by MediaU

Hi, I’m looking for media player integration of my internet radios (Oakcastle). I can control them via android phone with the AirMusic Control APP by MediaU. Some info I found on github:

https://gist.github.com/hsiboy/5662ee465979550452cf0470ff144353

https://github.com/kayrus/iradio

I know some other brands use this system like Auna or Sharp. I think this is fairly similar to Silikon Frontier integration - but I do not have any programing experiance to do enything myself.

Found some more info on github:

https://github.com/RobinMeis/AirMusic/tree/master/docs

https://github.com/vitasrutek/special-octo-waffle

https://github.com/edberoi/python-airmusicapi

The last one has na API - how to integrate this into HA?

I’ve installed on my raspberry pi 4 (not running HA - I run HA on a Lenovo M72e) the tests.py from https://github.com/edberoi/python-airmusicapi

And after running it on my two internet radios I get this info:

Device Name: Radio �azienka
{
“SW_Ver”: “AT9THFCR-i724h-i713**ad-i725a-(DB:20211111)”,
“wifi_info”: {
“status”: “connected”,
“MAC”: “0C8C243E5CE0”,
“SSID”: “DOM3”,
“Signal”: “76”,
“Encryption”: “WPA2/AES”,
“IP”: “192.168.0.141”,
“Subnet”: “255.255.255.0”,
“Gateway”: “192.168.0.1”,
“DNS1”: “192.168.0.91”,
“DNS2”: null
}
}
Current volume = 3
Current mute = False
Hotkeylist: 5 out of 5:
75_256, Muzo.fm, file
75_770, Antyradio 94 FM Warszawa, file
75_4, Rock Radio, file
75_0, Double Q 101 WWQQ FM 101.3, file
75_0, Radio TOK FM, file
Verify navigation through menus to reach a station to play.
List: 10 out of 10:
87 Local Radio → content
51 my mediaU → content
52 Internet Radio → content
2 Media Center → content
5 FM → content
91 DAB/DAB+ → content
3 Information Center → content
47 AUX → content
104 Bluetooth → content
6 Configuration → content
List: 6 out of 6:
75 My Favorite → content
71 Radio Station/Music → content
87 Local Radio → content
154 Sleep Radio → content
59 History → content
4 Service → content
List: 8 out of 8:
75_0 Muzo.fm → file
75_1 Antyradio 94 FM Warszawa → file
75_2 Rock Radio → file
75_3 Double Q 101 WWQQ FM 101.3 → file
75_4 Radio TOK FM → file
75_5 Radio Nowy Å�wiat → file
75_6 Rádio Anténa Rock → file
75_7 Empty → emptyfile
Press CTRL-C to interrupt.
Vol sid Status
3 1 Connecting …
3 1 Connecting …
3 1 Connecting …
3 1 Connecting …
3 1 Connecting …
3 1 Connecting …
3 1 Connecting …
3 1 Connecting …
3 1 Connecting …
3 1 Connecting …
^CGoing to play the radio station at hotkey 1.
Press CTRL-C to interrupt.
Vol sid Status
3 1 Connecting …
3 1 Connecting …
3 1 Connecting …
3 2 Buffering 25%
3 6 Playing
3 6 Playing
3 6 Playing

Second radio:

Device Name: Oakcastle IR100
{
“SW_Ver”: “5SADNB33-jb21h-jb21**a*-jb21a-(DB:20220114)”,
“wifi_info”: {
“status”: “connected”,
“MAC”: “74EE2A365265”,
“SSID”: “DOM3”,
“Signal”: “82”,
“Encryption”: “WPA2/AES”,
“IP”: “192.168.0.142”,
“Subnet”: “255.255.255.0”,
“Gateway”: “192.168.0.1”,
“DNS1”: “192.168.0.91”,
“DNS2”: null
}
}
Current volume = 10
Current mute = False
Hotkeylist: 5 out of 5:
75_0, Muzo.fm, file
75_1, Antyradio FM, file
75_2, Rock Radio, file
75_3, EskaROCK, file
75_4, Radio Nowy Swiat, file
Verify navigation through menus to reach a station to play.
List: 7 out of 7:
87 Local Radio → content
52 Internet Radio → content
2 Media Center → content
136 Spotify Connect → content
3 Information Center → content
104 Bluetooth → content
6 Configuration → content
List: 5 out of 5:
75 My Favorite → content
71 Radio Station/Music → content
154 Sleep Radio → content
59 History → content
4 Service → content
List: 10 out of 10:
75_0 Muzo.fm → file
75_1 Antyradio FM → file
75_2 Rock Radio → file
75_3 EskaROCK → file
75_4 Radio Nowy Swiat → file
75_5 ANTENA ROCK → file
75_6 Zlote → file
75_7 MELO- → file
75_8 TOK FM → file
75_9 Empty → emptyfile
Press CTRL-C to interrupt.
Vol sid Status
10 1 Connecting …
10 2 Buffering 25%
10 6 Playing
10 6 Playing
10 6 Playing
10 6 Playing
10 6 Playing
^CGoing to play the radio station at hotkey 1.
Press CTRL-C to interrupt.
Vol sid Status
10 6 Playing
10 1 Connecting …
10 3 Buffering 50%
10 6 Playing
10 6 Playing

If I run this script I can play Antyradio station:

import json
import logging
import time
from airmusicapi import airmusic

IPADDR = ‘192.168.0.142’ # Change this to the IP-address or hostname of your device.
TIMEOUT = 5 # in seconds. In most cases 1 second is sufficient.

def main():

am_obj = airmusic(IPADDR, TIMEOUT)
am_obj.log_level = logging.DEBUG
am_obj.init(language="en")

hotkeylist = am_obj.get_hotkeylist()

am_obj.enter_menu(75)
am_obj.play_station('75_1')

am_obj.play_hotkey(1)

if name == ‘main’:
main()

So the control of the radios via IP works fine, rest of the commands are in the airmusicapi init.py file. Now how to integrate this into Home Assistant?

So after some thinking I used shell_command to get this done:

shell_command:
  kuchnia_on_off: "curl -H 'Authorization: Basic c3UzZzRnbzZzazc6amkzOTQ1NHh1L14=' http://192.168.0.142/Sendkey?key=7"
  kuchnia_vol_up: "curl -H 'Authorization: Basic c3UzZzRnbzZzazc6amkzOTQ1NHh1L14=' http://192.168.0.142/Sendkey?key=9"
  kuchnia_mute: "curl -H 'Authorization: Basic c3UzZzRnbzZzazc6amkzOTQ1NHh1L14=' http://192.168.0.142/Sendkey?key=8"
  kuchnia_vol_down: "curl -H 'Authorization: Basic c3UzZzRnbzZzazc6amkzOTQ1NHh1L14=' http://192.168.0.142/Sendkey?key=10"
  kuchnia_up: "curl -H 'Authorization: Basic c3UzZzRnbzZzazc6amkzOTQ1NHh1L14=' http://192.168.0.142/Sendkey?key=2"
  kuchnia_down: "curl -H 'Authorization: Basic c3UzZzRnbzZzazc6amkzOTQ1NHh1L14=' http://192.168.0.142/Sendkey?key=3"
  kuchnia_1: "curl -H 'Authorization: Basic c3UzZzRnbzZzazc6amkzOTQ1NHh1L14=' http://192.168.0.142/Sendkey?key=115"
  kuchnia_2: "curl -H 'Authorization: Basic c3UzZzRnbzZzazc6amkzOTQ1NHh1L14=' http://192.168.0.142/Sendkey?key=116"
  kuchnia_3: "curl -H 'Authorization: Basic c3UzZzRnbzZzazc6amkzOTQ1NHh1L14=' http://192.168.0.142/Sendkey?key=117"
  kuchnia_4: "curl -H 'Authorization: Basic c3UzZzRnbzZzazc6amkzOTQ1NHh1L14=' http://192.168.0.142/Sendkey?key=118"
  kuchnia_5: "curl -H 'Authorization: Basic c3UzZzRnbzZzazc6amkzOTQ1NHh1L14=' http://192.168.0.142/Sendkey?key=119"
  kuchnia_6: "curl -H 'Authorization: Basic c3UzZzRnbzZzazc6amkzOTQ1NHh1L14=' http://192.168.0.142/Sendkey?key=120"
  kuchnia_7: "curl -H 'Authorization: Basic c3UzZzRnbzZzazc6amkzOTQ1NHh1L14=' http://192.168.0.142/Sendkey?key=121"
  kuchnia_8: "curl -H 'Authorization: Basic c3UzZzRnbzZzazc6amkzOTQ1NHh1L14=' http://192.168.0.142/Sendkey?key=122"
  kuchnia_9: "curl -H 'Authorization: Basic c3UzZzRnbzZzazc6amkzOTQ1NHh1L14=' http://192.168.0.142/Sendkey?key=123"

And a simple button card grid layout to get a ‘remote’ card:

type: grid
cards:
  - show_name: true
    show_icon: true
    type: button
    name: Radio Kuchnia
    tap_action:
      action: call-service
      service: shell_command.kuchnia_on_off
      service_data: {}
      target: {}
    icon: mdi:power
    show_state: true
    hold_action:
      action: none
  - show_name: true
    show_icon: true
    type: button
    tap_action:
      action: call-service
      service: shell_command.kuchnia_up
      service_data: {}
      target: {}
    entity: ''
    icon: mdi:arrow-up-bold
  - show_name: true
    show_icon: true
    type: button
    tap_action:
      action: call-service
      service: shell_command.kuchnia_down
      service_data: {}
      target: {}
    icon: mdi:arrow-down-bold
  - show_name: true
    show_icon: true
    type: button
    tap_action:
      action: call-service
      service: shell_command.kuchnia_vol_up
      service_data: {}
      target: {}
    icon: mdi:volume-plus
    show_state: true
    hold_action:
      action: none
  - show_name: true
    show_icon: true
    type: button
    tap_action:
      action: call-service
      service: shell_command.kuchnia_vol_down
      service_data: {}
      target: {}
    icon: mdi:volume-minus
    show_state: true
    hold_action:
      action: none
  - show_name: true
    show_icon: true
    type: button
    tap_action:
      action: call-service
      service: shell_command.kuchnia_mute
      service_data: {}
      target: {}
    icon: mdi:volume-mute
  - show_name: true
    show_icon: true
    type: button
    tap_action:
      action: call-service
      service: shell_command.kuchnia_1
      service_data: {}
      target: {}
    icon: mdi:numeric-1
    name: Muzo.fm
  - show_name: true
    show_icon: true
    type: button
    tap_action:
      action: call-service
      service: shell_command.kuchnia_2
      service_data: {}
      target: {}
    name: Antyradio
    icon: mdi:numeric-2
  - show_name: true
    show_icon: true
    type: button
    tap_action:
      action: call-service
      service: shell_command.kuchnia_3
      service_data: {}
      target: {}
    icon: mdi:numeric-3
    name: RockRadio
  - show_name: true
    show_icon: true
    type: button
    tap_action:
      action: call-service
      service: shell_command.kuchnia_4
      service_data: {}
      target: {}
    icon: mdi:numeric-4
    name: EskaRock
  - show_name: true
    show_icon: true
    type: button
    tap_action:
      action: call-service
      service: shell_command.kuchnia_5
      service_data: {}
      target: {}
    icon: mdi:numeric-5
    name: Radio Nowy Świat
  - show_name: true
    show_icon: true
    type: button
    tap_action:
      action: call-service
      service: shell_command.kuchnia_6
      service_data: {}
      target: {}
    icon: mdi:numeric-6
    name: Antena Rock
  - show_name: true
    show_icon: true
    type: button
    tap_action:
      action: call-service
      service: shell_command.kuchnia_7
      service_data: {}
      target: {}
    icon: mdi:numeric-7
    name: Złote Przeboje
  - show_name: true
    show_icon: true
    type: button
    tap_action:
      action: call-service
      service: shell_command.kuchnia_8
      service_data: {}
      target: {}
    icon: mdi:numeric-8
    name: MeloRadio
  - show_name: true
    show_icon: true
    type: button
    tap_action:
      action: call-service
      service: shell_command.kuchnia_9
      service_data: {}
      target: {}
    icon: mdi:numeric-9
    name: Tok FM

1 Like

Hi Dominik,
where did you get the Authorization Basic string, please ?

I got all the info from this page: https://github.com/edberoi/python-airmusicapi

Edit:
So I’ve wanted to check if my radio is playing or not in HA, by studing the dabman api you can find out that the sid value changes once the radio is playing or not playing, thanks to this i created an NodeRED flow to check for the current value and to send info if the radio in on or off:

The flow:

[{"id":"03baef9ddf0a2449","type":"inject","z":"beda68e300d2159f","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"10","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":110,"y":160,"wires":[["97c886cbde476b8e"]]},{"id":"97c886cbde476b8e","type":"http request","z":"beda68e300d2159f","name":"Kuchnia","method":"GET","ret":"txt","paytoqs":"ignore","url":"192.168.0.142/background_play_status","tls":"","persist":false,"proxy":"","insecureHTTPParser":false,"authType":"basic","senderr":false,"headers":[],"x":260,"y":160,"wires":[["6285073c89e39fd3"]]},{"id":"6285073c89e39fd3","type":"xml","z":"beda68e300d2159f","name":"","property":"payload","attr":"","chr":"","x":390,"y":160,"wires":[["05c735b1d3fcea99"]]},{"id":"05c735b1d3fcea99","type":"change","z":"beda68e300d2159f","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"payload.result.sid[0]","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":540,"y":160,"wires":[["fc44f2aa3edfdaf2"]]},{"id":"8a7a56c3e3034af9","type":"ha-entity","z":"beda68e300d2159f","name":"","server":"b4642eb.26c79d","version":2,"debugenabled":false,"outputs":1,"entityType":"sensor","config":[{"property":"name","value":"Radio Kuchnia"},{"property":"device_class","value":""},{"property":"icon","value":""},{"property":"unit_of_measurement","value":""},{"property":"state_class","value":""},{"property":"last_reset","value":""}],"state":"payload","stateType":"msg","attributes":[],"resend":true,"outputLocation":"payload","outputLocationType":"none","inputOverride":"allow","outputOnStateChange":false,"outputPayload":"","outputPayloadType":"str","x":910,"y":160,"wires":[[]]},{"id":"fc44f2aa3edfdaf2","type":"change","z":"beda68e300d2159f","name":"","rules":[{"t":"change","p":"payload","pt":"msg","from":"1","fromt":"str","to":"off","tot":"str"},{"t":"change","p":"payload","pt":"msg","from":"6","fromt":"str","to":"on","tot":"str"},{"t":"change","p":"payload","pt":"msg","from":"7","fromt":"str","to":"on","tot":"str"},{"t":"change","p":"payload","pt":"msg","from":"2","fromt":"str","to":"on","tot":"str"},{"t":"change","p":"payload","pt":"msg","from":"3","fromt":"str","to":"on","tot":"str"},{"t":"change","p":"payload","pt":"msg","from":"4","fromt":"str","to":"on","tot":"str"},{"t":"change","p":"payload","pt":"msg","from":"5","fromt":"str","to":"on","tot":"str"},{"t":"change","p":"payload","pt":"msg","from":"9","fromt":"str","to":"on","tot":"str"},{"t":"change","p":"payload","pt":"msg","from":"12","fromt":"str","to":"on","tot":"str"},{"t":"change","p":"payload","pt":"msg","from":"14","fromt":"str","to":"on","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":730,"y":160,"wires":[["8a7a56c3e3034af9"]]},{"id":"b4642eb.26c79d","type":"server","name":"Home Assistant main","version":4,"addon":true,"rejectUnauthorizedCerts":true,"ha_boolean":"y|yes|true|on|home|open","connectionDelay":true,"cacheJson":true,"heartbeat":false,"heartbeatInterval":"30","areaSelector":"friendlyName","deviceSelector":"friendlyName","entitySelector":"friendlyName","statusSeparator":"at: ","statusYear":"hidden","statusMonth":"short","statusDay":"numeric","statusHourCycle":"h23","statusTimeFormat":"h:m"}]

And with this card I can see if the radio is on:

type: custom:button-card
show_name: true
show_icon: true
name: Radio Kuchnia
tap_action:
  action: call-service
  service: shell_command.kuchnia_on_off
  service_data: {}
  target: {}
icon: mdi:power
show_state: false
state_color: true
hold_action:
  action: none
entity: sensor.radio_lazienka_2
aspect_ratio: 1/1

Works great!