We turn the gateway of the smart home Xiaomi into a column
- Tutorial
Hi, Habra Giktayms reader! Today I will teach you how to get useful from useless functionality. We will receive on the example of a smart home from the well-known company Xiaomi and its product in the form of a ZigBee gateway.
The owners of Xiaomi smart home components know that most of them are divided into those who can communicate via zigbee or bluetooth. We will be interested in the gateway for zigbee devices version 2, since It was there that the radio functionality appeared, which by default only Chinese Internet radio stations can play.

Of course, there is a project on the Internet that can be used to add various other radio stations, but we will go a different way and create a wireless column from the gateway.
For the successful implementation of the operation you need:
In order to make a wireless column from our gateway, you need to pretend to be an Internet radio stream and train the gateway that knocking at the list of stations is necessary for us, and not for the Chinese API.
In order to understand how the application on the phone communicates with Chinese servers, you can download traffic, but I will save you from this hemorrhoids :) Those who want to expand their horizons - you can do this optional.
So, we will be interested in three requests and, accordingly, a response to the Chinese API, which lives at api.ximalaya.com:
The word openapi in the way hints at something open, but I did not find the public specification. The request comes with parameters that are not needed for our purposes, so we discard them.
I used nginx as a web server, here is the config:
Create the same hierarchy at the root of your web server. Additionally, create radio and hls folders in the root of the web server. All calls on these paths should output the same JSON, so it makes sense to make them links to a file, which we call stations.json.
Here is its contents:
As you can see, everything is simple - we give the array of radio indicating where to look for the stream. If you have multiple gateways, you can make multiple channels. Important note - the address indicated here must be accessible from the gateway!
In order for the application to see your changes, you need to edit the hosts on your smartphone and register there the correspondence api.ximalaya.com to the address of your web server.
Now how to receive a flow. I decided to output everything from my sound card from the PC on which the web server was deployed. For this we will use ffmpeg:
Pay attention to the path and address of the web server - substitute yours.
In principle, this is all for successful work - run the ffmpeg script, it will start creating segments with sound from your sound card, run the application on the phone and select your station - in a second or two there should be sound from the PC.
The owners of Xiaomi smart home components know that most of them are divided into those who can communicate via zigbee or bluetooth. We will be interested in the gateway for zigbee devices version 2, since It was there that the radio functionality appeared, which by default only Chinese Internet radio stations can play.

Of course, there is a project on the Internet that can be used to add various other radio stations, but we will go a different way and create a wireless column from the gateway.
What do you need?
For the successful implementation of the operation you need:
- Actually, ZigBee itself has a gateway version of at least 2 (a radio appeared in it)
- Any web server
- A smartphone that has a root and installed software MiHome c selected country China Mainland
What do we do?
In order to make a wireless column from our gateway, you need to pretend to be an Internet radio stream and train the gateway that knocking at the list of stations is necessary for us, and not for the Chinese API.
In order to understand how the application on the phone communicates with Chinese servers, you can download traffic, but I will save you from this hemorrhoids :) Those who want to expand their horizons - you can do this optional.
So, we will be interested in three requests and, accordingly, a response to the Chinese API, which lives at api.ximalaya.com:
- / openapi-gateway-app / live / radios
- / openapi-gateway-app / live / get_radios_by_ids
- / openapi-gateway-app / search / radios
The word openapi in the way hints at something open, but I did not find the public specification. The request comes with parameters that are not needed for our purposes, so we discard them.
I used nginx as a web server, here is the config:
server {
listen *:80;
server_name api.io.mi.com ximalaya.com www.ximalaya.com api.ximalaya.com mobile.ximalaya.com open.ximalaya.com ximiraga.ru www.ximiraga.ru;
root /opt/xiaomiradio/www;
index index.php index.html index.htm;
access_log /var/log/nginx/radio_access.log;
error_log /var/log/nginx/radio_error.log;
location@ximalaya {
proxy_pass http://api.ximalaya.com;
}
}
Create the same hierarchy at the root of your web server. Additionally, create radio and hls folders in the root of the web server. All calls on these paths should output the same JSON, so it makes sense to make them links to a file, which we call stations.json.
Here is its contents:
{
"total_page":1,
"total_count":1,
"current_page":0,
"radios":[
{
"id":527782023,
"kind":"radio",
"program_name":"AirSound1",
"radio_name":"AirSound1",
"radio_desc":"",
"schedule_id":0,
"support_bitrates":[
64
],
"rate24_aac_url":"",
"rate64_aac_url":"http://<ваш адрес в локальной сети>/hls/live1.m3u8",
"rate24_ts_url":"",
"rate64_ts_url":"",
"radio_play_count":1,
"cover_url_small":"http://<ваш адрес в локальной сети>/radio/527782023/cover_small.png",
"cover_url_large":"http://<ваш адрес в локальной сети>/radio/527782023/cover_big.png",
"updated_at":0,
"created_at":0
}
]
}
As you can see, everything is simple - we give the array of radio indicating where to look for the stream. If you have multiple gateways, you can make multiple channels. Important note - the address indicated here must be accessible from the gateway!
In order for the application to see your changes, you need to edit the hosts on your smartphone and register there the correspondence api.ximalaya.com to the address of your web server.
Now how to receive a flow. I decided to output everything from my sound card from the PC on which the web server was deployed. For this we will use ffmpeg:
#!/bin/bash
ffmpeg -f alsa -i hw:Loopback,1,0 -c:a libfdk_aac -b:a 64k -f ssegment -segment_list /opt/xiaomiradio/hls/live1.m3u8 -segment_list_flags +live -segment_time 1 -segment_list_size 1 -segment_wrap 5 -segment_list_entry_prefix http://<ваш адрес в локальной сети>/hls/ /opt/xiaomiradio/hls/64%03d.aac
Pay attention to the path and address of the web server - substitute yours.
In principle, this is all for successful work - run the ffmpeg script, it will start creating segments with sound from your sound card, run the application on the phone and select your station - in a second or two there should be sound from the PC.