Reliable Subwoofer Automation using Volumio MQTT & OpenHAB

[Guide] Reliable Subwoofer Automation using Volumio MQTT & OpenHAB

I’ve been an OpenHAB user for almost 10 years, toggling between the Volumio and MPD bindings to automate my subwoofer power. While those bindings are feature-rich, I found them a bit “heavy” and inconsistent for just a simple On/Off trigger.

The Volumio MQTT Client plugin is the perfect “no-nonsense” solution (great work @nerd) It’s lightweight, fast, and stays in sync without the overhead of a full binding. I’ve paired this with a Tasmota-flashed Sonoff Basic to handle the power.

I also implemented a 30-second delay in the logic. This prevents the sub from clicking on and off constantly when switching radio stations or skipping tracks—Volumio often sends a brief ‘stop’ or ‘pause’ signal during those transitions.

1. The MQTT Thing (Bridge)

Note: This assumes you have a Mosquitto broker running. Update the stateTopic to match your Volumio hostname.

Thing mqtt:topic:mosquitto:volumio_mqtt "Volumio" (mqtt:broker:mosquitto) {
    Channels:
        Type string : state "Playback State" [ stateTopic="volumio/volumio/status/state" ]
}

2. The Item

String Volumio_MQTT_State { channel="mqtt:topic:mosquitto:volumio_mqtt:state" }
Switch Sub_Speaker "Subwoofer Power" { channel="mqtt:topic:mosquitto:your_tasmota_sonoff:power" }

3. The Automation Rule (with 30s Buffer)

var Timer subOffTimer = null

rule "Subwoofer Auto Power Logic"
when
    Item Volumio_MQTT_State received update
then
    val status = Volumio_MQTT_State.state.toString.toLowerCase

    if (status == "play") {
        // Cancel off-timer if music resumes
        if (subOffTimer !== null) {
            subOffTimer.cancel
            subOffTimer = null
        }
        
        // Turn Sub ON
        if (Sub_Speaker.state != ON) {
            Sub_Speaker.sendCommand(ON)
        }
    } 
    
    else if (status == "pause" || status == "stop") {
        // Start 30s countdown before cutting power
        if (subOffTimer === null) {
            subOffTimer = createTimer(now.plusSeconds(30), [ |
                if (Volumio_MQTT_State.state.toString.toLowerCase != "play") {
                    Sub_Speaker.sendCommand(OFF)
                }
                subOffTimer = null
            ])
        }
    }
end

Hopefully, this helps anyone else looking for a bulletproof way to manage their hardware power without relying on complex bindings!

Cheers
Matt