A little audio section & notes

I use a couple of Wiim products at home for music streaming – a Mini in my home office, and a Pro in the lounge. Both are using S.M.S.L. SU1 DACs.

The Wiim Pro is a Chromecast capable device – pretty much anything can be used to control it and stream. The Mini is not Chromecast. Both have a web API, and a UPnP interface. I was able to find some projects on Github that show how to build code to drive these from Linux, or as ready apps to use.

https://www.wiimhome.com/pdf/HTTP%20API%20for%20WiiM%20Mini.pdf – API doccumentation

https://wiki.gnome.org/Projects/GUPnP – a Linux based UPnP set of tools for discovery and experimentation. Very helpful with building and debugging UPnP code when working with devices like the Wiims

https://github.com/retired-guy/WiiM-Watcher-Chrome-Extension – Chrome js. Check out some of the other examples from this user too.

https://github.com/shumatech/wiimplay – app written in Go, runs great on Linux. Precompiled binary available


Wiim Play driving my office Mini from a Linux desktop

Simple Python Demo for a Wiim Mini control
Enter the IP address of your Wiim device into target_ip

You need to have started the Wiim playing something via a phone / tablet with Wiim Home / Tidal / Spotify. The app allows the user to pause / play / skip to the next or previous track.


# Begin

import tkinter as tk
import requests
requests.packages.urllib3.disable_warnings()


# Specify the IP address here
target_ip = "192.168.1.72"

def get_now_playing():
    url = f"https://{target_ip}/httpapi.asp?command=getStatusEx"
    response = requests.get(url, verify=False)
    data = response.json()
    return data

def play():
    url = f"https://{target_ip}/httpapi.asp?command=setPlayerCmd:resume"
    response = requests.get(url, verify=False)
    update_ui()

def pause():
    url = f"https://{target_ip}/httpapi.asp?command=setPlayerCmd:onepause"
    response = requests.get(url, verify=False)
    update_ui()

def next_track():
    url = f"https://{target_ip}/httpapi.asp?command=setPlayerCmd:next"
    response = requests.get(url, verify=False)
    update_ui()

def previous_track():
    url = f"https://{target_ip}/httpapi.asp?command=setPlayerCmd:prev"
    response = requests.get(url, verify=False)
    update_ui()

def update_ui():
    now_playing = get_now_playing()
    ssid = now_playing.get("ssid", "Unknown SSID")
    device_name = now_playing.get("DeviceName", "Unknown Device")

    status_label.config(text=f"SSID: {ssid}\nDevice Name: {device_name}")


def create_buttons(root):
    char = chr(0x25BA)    
    play_button = tk.Button(root, text=char + " Play", command=play)
    play_button.pack()
    char2 = chr(0x23EF)
    pause_button = tk.Button(root, text=char2, command=pause)
    pause_button.pack()
    char3 = chr(0x23ED)
    next_button = tk.Button(root, text=char3, command=next_track)
    next_button.pack()
    char4 = chr(0x23EE)
    prev_button = tk.Button(root, text=char4, command=previous_track)
    prev_button.pack()

def main():
    root = tk.Tk()
    root.title("WiiM Mini Control")

    global status_label
    status_label = tk.Label(root, text="")
    status_label.pack()

    create_buttons(root)
    update_ui()

    root.mainloop()

if __name__ == "__main__":
    main()