[TUTORIAL] Sharing information between BASH and Gladys

Hello,

I offer 2 TUTORIALS that explain how to use BASH commands to send data to Gladys and to receive data from it.

BASH is simple to use and is present on many GNU/Linux systems (such as Raspberry) and will in any case be reproducible for another SHELL.
It allows executing any system command and managing the entire PC.

For communication, you must use the MQTT protocol.
Gladys very kindly offers to install an MQTT broker in one click via Integration > MQTT > Configuration > Use a broker in a Docker container.

Once installed, you can create devices via Integration > MQTT > Devices > New.


TUTORIAL n°1 : Display the Raspberry temperature in Gladys.
The idea is therefore to retrieve the Raspberry temperature via a BASH script and send it to Gladys.


On the Gladys side:

  1. Creating the device:
    Name : Raspberry Temperature
    External Id : mqtt:Salle:RaspTemp (mqtt:Room:Element)
    Room : Salle

  2. **Adding a feature of type : **
    Name : Raspberry Temperature
    Feature external ID : mqtt:RaspTemp:temp (mqtt:Element:Function)
    Unit : °C
    Minimum value : 0 (to reach this temperature you’d have to cool it with nitrogen…)
    Maximum value : 110 (perfect for using it as a heater)
    Keep state history : Yes
    Is it a sensor : Yes
    MQTT topic to publish : You can set aside the topic that will be used later.

  3. Adding the device to the dashboard:

Nothing specific here, proceed as usual.

That’s it, we’re done with Gladys :slight_smile:


On the BASH side:
Let’s move on to the BASH scripts that I will put in /opt/mosquittos/ (or another location of your choice but you will need to adapt the paths).

I comment the code as much as possible so it is as understandable as possible; feel free to read it.

  1. Creating a common script /opt/mosquitto/MQTTConfig.sh :

It will be sourced by the others (different TUTORIALS), it contains :
A function testing the required commands and packages to install (for Ubuntu) if necessary.
The connection credentials for the MQTT broker created by Gladys accessible via Integration > MQTT > Configuration.
Variables to color the output.

#!/bin/bash

#############################################
## File to source in MQTT scripts         ##
#############################################

### Variables to customize
# Connection to the MQTT broker
User="gladys"
Pass="XYZ"
### Variables to customize


function CommandCheck()
{
    # Function checking for the presence of required commands
    # Parameter: Command name and package (optional) separated by :
        # e.g.: mosquitto_pub:mosquitto-clients

    # If no parameter is given
    [[ -z ${1} ]] && return 1

    # Limit variables to the function
    local Command Package Parameter ReturnValue
    ReturnValue=0

    # Process all parameters
    for Parameter in "${@}"
    do
        Command="${Parameter%%:*}"
        Package="${Parameter##*:}"

        # If the command does not exist
        if ! which ${Command} &>/dev/null
        then
            # Set return value to 1 to display all echos before stopping
            ReturnValue=1

            echo -e "[${ROUGE}Erreur${RAZ}] ArrĂŞt du script car la commande ${BLEUFONCE}${Command}${RAZ} est introuvable." 1>2

            # If a package is given
            [[ ${Package} ]] && echo -e "Pour ubuntu : ${FUCHSIA}sudo apt-get install ${Package}${RAZ}" 1>2
        fi
    done

    return ${ReturnValue}
}

# Colors for output
FUCHSIA="\\e[1;35m"
RAZ="\\e[m"
BLEUFONCE="\\e[1;34m"
ROUGE="\\e[1;31m"
ORANGE="\\e[1m\\[\\e[38;5;202m\\]"

Only the variables between ### Variables to customize need to be adapted.

  1. Creating the script /opt/mosquitto/BashToGladys.sh :

Its purpose is to retrieve the Raspberry temperature at regular intervals and send this information to Gladys.

#/bin/bash

###################################################
## Sending the Raspberry temperature to Gladys  ##
###################################################

### Variables to customize
# Number of seconds between temperature retrievals
# A small value is not a very good idea...
TimeOut=60

# Device topic address
# Available in Gladys > Integration > MQTT > Devices > Raspberry Temperature > Temperature > MQTT topic to publish
Topic="gladys/master/device/mqtt:Salle:RaspTemp/feature/mqtt:RaspTemp:temp/state"
### Variables to customize

# Loading the common file
source /opt/mosquitto/MQTTConfig.sh

# Check for required commands which, if missing, will stop the script
# Requires the mosquitto_pub command from package mosquitto-clients
! CommandCheck "mosquitto_pub:mosquitto-clients" && exit 1

# Block the script if TimeOut is less than 1
if [[ ${TimeOut:-0} -lt 1 ]]
then
    echo -e "[${ROUGE}Erreur${RAZ}] Le TimeOut est inadapté." 1>2
    exit 1
fi

# Infinite loop
while true
do
    # Retrieve the Raspberry temperature
    Temperature=$(/usr/bin/vcgencmd measure_temp)
    Temperature=${Temperature//[^0-9.]/}

    # If the variable is not empty
    if [[ ${Temperature} ]]
    then
        # Display the info in the SHELL
        echo -e "[${FUCHSIA}$(date +'%x %X')${RAZ}] La température du Raspberry est de ${BLEUFONCE}${Temperature}°c${RAZ}."

        # Send the information to Gladys with mosquitto_pub
        # -u User : User for connecting to the MQTT broker, comes from MQTTConfig.sh
        # -P Pass : Password for connecting to the MQTT broker, comes from MQTTConfig.sh
        # -t Topic : Address of the device Topic created in Gladys, defined at the top of the script
        # -m Temperature : Use the temperature
        mosquitto_pub -u "${User}" -P "${Pass}" -t "${Topic}" -m "${Temperature}"

        # Get the return value of the mosquitto_pub command
        MosquittoReturns=${?}

        # Display mosquitto error code if return code > 0
        (( ${MosquittoReturns} )) && echo -e "[${ROUGE}Erreur${RAZ}] La commande mosquitto_sub a renvoyé le code ${MosquittoReturns}." 1>2

    # If the temperature variable is empty
    else
        # Display an error message
        echo -e "[${ROUGE}Erreur${RAZ}] Température non récupérée." 1>2
    fi

    # Pause the script for the requested time
    sleep "${TimeOut}"
done

Only the variables between ### Variables to customize need to be adapted.

  1. Running the script:

Just run:

bash /opt/mosquitto/BashToGladys.sh

With a TimeOut of 60 seconds, it then displays:

[16/02/2023 10:35:05] La température du Raspberry est de 39.4°c.
[16/02/2023 10:36:05] La température du Raspberry est de 40.4°c.
[16/02/2023 10:37:05] La température du Raspberry est de 40.4°c.
[16/02/2023 10:38:05] La température du Raspberry est de 39.9°c.
…

And the value is properly updated in Gladys.

If the mosquitto_pub command does not exist, the script displays:

[Erreur] ArrĂŞt du script car la commande mosquitto_pub est introuvable.
Pour ubuntu : sudo apt-get install mosquitto-clients

If everything works, you just need to run the script at Raspberry startup (crontab or other).

Limitation :
It is only possible to send integers and floating point numbers to Gladys.
Sending text does not work, no error is emitted but nothing is displayed.


Other tutorials:

TUTORIAL n°2: Run a BASH command via a Gladys action., in the message below.

TUTORIAL n°3: Indicate the presence of a user via their phone’s Wi-FI.

TUTORIAL n°4: Managing your vacuum robot under Valetudo in Gladys.

5 Likes

TUTORIAL No.2: Run a BASH command via a Gladys action.
The idea is to monitor a Gladys device topic from BASH and execute the appropriate commands.


Gladys side:

  1. Device creation:
    Name : Appel BASH
    External ID : mqtt:Salle:AppelBASH
    Room : Salle

  2. Add a feature of type Button Click (for example):
    Name : Appel BASH
    Feature external ID : mqtt:AppelBASH:Action
    Min value : 0
    Max value : 9 (Allows 10 different actions)
    Keep state history : Yes
    Is it a sensor : No
    MQTT topic to listen to : You can note the topic that will be used later.

  3. Define a scene:
    Trigger : One of your choice (such as the state change of a real button, for example).
    Action : Control a device.
    Device : Appel BASH
    Value : 1 (between 0 and 9)

You will only need to trigger the scene once the BASH scripts are finished.


BASH scripts.

  1. Reuse the common script /opt/mosquitto/MQTTConfig.sh from TUTORIAL No.1.

  2. Create the script /opt/mosquitto/GladysToBash.sh :
    It will listen to the topic of the device created in Gladys.

#!/bin/bash

#####################################################################
## Monitoring a Gladys topic with execution of BASH commands ##
#####################################################################

### Variables to customize
# You must customize the CASE in the WHILE loop.

# Device topic address
# Available in Gladys > Integration > MQTT > Devices > Appel BASH > Button Click > MQTT topic to listen to
Topic="gladys/device/mqtt:salle:AppelBASH/feature/mqtt:AppelBASH:Action/state"
### Variables to customize

# Load the common file
source /opt/mosquitto/MQTTConfig.sh

# Requires the mosquitto_sub command from the mosquitto-clients package
! CommandCheck "mosquitto_sub:mosquitto-clients" \u0026\u0026 exit 1

echo "Le script attend de recevoir les commandes de Gladys." 1\u003e\u00262
echo "Il ne rend la main que si des break et exit sont intégrés à la boucle while." 1\u003e\u00262

# Loop continuously listening to the Gladys device topic
# -u User : User for connecting to the MQTT broker, comes from MQTTConfig.sh
# -P Pass : Password for connecting to the MQTT broker, comes from MQTTConfig.sh
# -t Topic : Address of the Topic of the device created in Gladys, defined at the beginning of the script
# Capture the returns into the variable Value
while read Value
do
    # Skip processing if Value is not between 0 and 9
    if [[ "${Value}" != [0-9] ]]
    then
        echo -e "[${ORANGE}Attention${RAZ}] Valeur ${Value} inconnue..." 1\u003e\u00262
        continue
    fi

    echo -e "[${FUCHSIA}$(date +'%x %X')${RAZ}] Exécution de la commande n°${Value}."

    # Case to perform the correct action depending on Value
    # Use of echo to avoid actually executing the commands in this TUTORIAL
    case "${Value}" in
        # Reboot the Raspberry
        0) echo sudo reboot ;;

        # Wake up a PC via WakeOnLan in the background so as not to block the loop
        1) echo wakeonlan XX:YY:ZZ:ZZ:YY:XX \u0026 ;;

        # Start an alarm via a wav file in vlc in the background so as not to block the loop
        2) echo vlc "/opt/alarme.wav" \u0026 ;;

        # Kill all vlc commands
        3) echo killall vlc ;;

        # Any other actions of your choice...
        [3-9]) echo "Réalisation de l'action ${Value}.";;
    esac
done \u003c \u003c(mosquitto_sub -u "${User}" -P "${Pass}" -t "${Topic}")

You must adapt the variables between ### Variables to customize as well as the actions in the case of the while loop.

For information, it is possible to specify the number of messages expected by mosquitto_sub before it returns control:

mosquitto_sub -u "${User}" -P "${Pass}" -t "${Topic}" -C x # Where x is the number of messages
  1. Script execution:

Just call the script with a simple:

bash /opt/mosquitto/GladysToBash.sh

The script does not return control to the prompt, this is normal; the loop is infinite.
It displays:

The script is waiting to receive commands from Gladys.
It only returns control if break and exit are integrated into the while loop.

  1. Executing the desired scene from Gladys:

Nothing special here; just execute the scene manually or via another device.
The shell then displays:

[16/02/2023 11:35:05] Execution of command No.5.
[16/02/2023 11:35:55] Execution of command No.2.
[16/02/2023 11:45:55] Execution of command No.3.

If everything works, the only thing left is to run the script at Raspberry startup.


Other tutorials:

TUTORIAL No.1: Display the Raspberry temperature in Gladys.

TUTORIAL No.3: Indicate a user’s presence via their phone’s Wi‑Fi.

TUTORIAL No.4: Managing your robot vacuum running Valetudo in Gladys.

7 Likes

Great stuff! Great job and great explanations, thank you so much!!! :+1:

Thank you for your contribution @Hizo! :pray: Great tutorial :slight_smile:

Thanks @Hizo, this will be really useful to me — I wanted to be able to do this but didn’t have the time.
:folded_hands::folded_hands:

Given how long it took me to figure out how it works (I’m a bit slow-witted…),
I thought it would surely help others save time.

And it’s a way to contribute my bit to this great program.

And as a Linux user, it’s also a way to give back what people have given me.

In any case, don’t hesitate to give me feedback if you use it.

TUTO 3, which will push the complexity of bash, is on standby as long as I don’t know how to display text.
It’s the only blocking but important element because it represents half of the information sent by the vacuum.

1 Like

We need to create this type of device in the

Hi @Hizo,
I followed the procedure as much as I could but when I run the command:
bash /opt/mosquitto/BashToGladys.sh, I get the following output:

: No such file or directory.sh: line 18: /opt/mosquitto/MQTTConfig.sh
/opt/mosquitto/BashToGladys

Hi, are you sure you did it correctly:

You’re missing the function, search the page for CommandCheck