Saturday, April 24, 2021

Simple MQTT handler in bash

How to subscribe to an MQTT topic efficiently in bash.

The context is of Raspberry Pi which controls a pool pump and these topics :

  • /pool/pump/action 0  # Command, set externally (sub) 
  • /pool/pump/state  1  # Actual state (pub, for feedback)

The pump is controlled via a solid state relay on GPIO 4.

''

#!/bin/bash
[[ $(pidof -x "$(basename $0)") != $$ ]] && exit
echo "Started $0 watcher..."

mqtt()
{
    action="$1"
    shift
    "mosquitto_${action}" -h 192.168.1.2 -t "$@"
}

raspi_out()
{
    pin=${1-22}
    state=${2-0}
    echo $pin   > /sys/class/gpio/export 2>/dev/null
    echo out    > /sys/class/gpio/gpio$pin/direction 2>/dev/null
    echo $state > /sys/class/gpio/gpio$pin/value
}

handler()
{
    new_state=$(echo "$1" | sed 's/[^01]//g')
    [[ -z "$new_state" ]] && new_state="0"

    if raspi_out 4 "$new_state"; then
        echo "pump state change OK, now $new_state"
    else
        echo "ERROR: pump state change fail towards $new_state"
    fi

    # Ping back
    real_state=$(cat /sys/class/gpio/gpio4/value)
    mqtt pub '/pool/pump/state' -m "$real_state" -r
}

export -f mqtt
export -f handler

# Wait for orders
mqtt sub '/pool/pump/action' |\
    xargs -n 1 -I {} /bin/bash -c 'handler "$@"' _ {}
''

No comments:

Post a Comment