Skip to content

Instantly share code, notes, and snippets.

@BOSSoNe0013
Last active January 20, 2026 08:46
Show Gist options
  • Select an option

  • Save BOSSoNe0013/07cfc222d4930240d3660be903dc0458 to your computer and use it in GitHub Desktop.

Select an option

Save BOSSoNe0013/07cfc222d4930240d3660be903dc0458 to your computer and use it in GitHub Desktop.
Send Podman ps to MQTT broker to watch containers status in HomeAssistant
#!/bin/bash
# _ ___ _ _
# ___ ___ _| |_____ ___ ___|_ |_____ ___| |_| |_
# | . | . | . | | .'| | _| | . | _| _|
# | _|___|___|_|_|_|__,|_|_|___|_|_|_|_ |_| |_|
# |_| |_|
#
# Copyright (C) 2026 Cyril Bosselut
#
# podman2mqtt is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# podman2mqtt is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with podman2mqtt If not, see <http://www.gnu.org/licenses/>.
PID="$$"
DAEMON=false
v_major=1
v_minor=1
v_patch=0
VERSION="$v_major.$v_minor.$v_patch"
function print_help {
echo "This script watch the podman containers status and update MQTT topics."
echo
echo "Syntax:"
echo " podman2mqtt.sh [-d|h|v]"
echo "options:"
echo " -d Run as a daemon."
echo " -h Print this Help."
echo " -v Print software version and exit."
echo
}
while getopts ":dvh" option; do
case $option in
d) #daemon
DAEMON=true;;
v) #display version
echo $VERSION
exit;;
h) #display help
print_help
exit;;
esac
done
function cwords {
local input="$1"
echo "$input" | sed 's/_/ /g' | sed 's/\b\w/\U&/g'
}
function onexit {
podman2mqtt_running=false
log "Bye !"
exit
}
function log {
local now=$(date +"%x %T")
if [[ $DAEMON == false ]]; then
echo "$now - $1" 1>&2
fi
logger --id="$PID" -t "podman2mqtt" "$1"
}
function contains {
local value=$1
shift
local arr=("$@")
for element in "${arr[@]}"; do
if [[ "$element" == "$value" ]]; then
echo true
fi
done
echo false
}
function main {
podman2mqtt_running=true
local registered_containers=()
if [[ $DAEMON == false ]]; then
echo "#####################################################"
echo "# _ ___ _ _ #"
echo "# ___ ___ _| |_____ ___ ___|_ |_____ ___| |_| |_ #"
echo "# | . | . | . | | .'| | _| | . | _| _| #"
echo "# | _|___|___|_|_|_|__,|_|_|___|_|_|_|_ |_| |_| #"
echo "# |_| |_| #"
echo "# #"
echo "#####################################################"
echo "Ver: $VERSION"
echo ""
fi
log "Starting podman2mqtt with PID: $PID"
log "Reverse DNS: $PODMAN2MQTT_RDNS"
local podman_state="OFF"
local first_run=true
while $podman2mqtt_running == true; do
log "### Updating containers status ###"
local check_state=`systemctl status podman.socket | grep 'active (running)'`
if [[ $check_state != "" ]]; then
podman_state="ON"
fi
if [[ $first_run == true ]]; then
log "Registering Podman"
mosquitto_pub -r -t "homeassistant/binary_sensor/podman/state/config" -m "{\"name\":\"state\",\"dev\":{\"name\":\"Podman\",\"ids\":[\"podman_$HOSTNAME\"]},\"uniq_id\":\"sensors.podman.state\",\"dev_cla\":\"running\",\"stat_t\":\"$HOSTNAME/podman/state\",\"val_tpl\":\"{{ value_json.state }}\",\"json_attr_t\":\"$HOSTNAME/podman/state\",\"ic\":\"mdi:docker\"}" --insecure
fi
first_run=false
local json=`podman ps -a --format=json`
local l=$(expr `echo $json | jq 'length'` - 1)
if [ $l > 0 ]; then
local running_containers=()
for (( i=0; i<=$l; i++ )); do
local data=`echo $json | jq ".[$i]"`
local container_id=`echo $data | jq -r ".Id"`
local name=`echo $data | jq -r ".Names[0]"`
running_containers+=("$name")
local registered=`contains $name "${registered_containers[@]}"`
local state="OFF"
local state_str=`echo $data | jq -r ".State"`
local id="podman2mqtt.$HOSTNAME.$name"
if [[ $state_str == "running" ]]; then
state="ON"
fi
local status_str=`echo $data | jq -r ".Status"`
local startedAt=`echo $data | jq -r ".StartedAt"`
local createdAt=`echo $data | jq -r ".Created"`
local cu=""
local support_url=""
local sw=""
local labels=`echo $data | jq -r ".Labels"`
if [ $PODMAN2MQTT_RDNS ]; then
local host_key="$PODMAN2MQTT_RDNS.host"
cu=`echo $labels | jq -r ".[\"$host_key\"]"`
log "cu: $cu"
if [[ $cu == "null" ]]; then
cu=`echo $labels | jq -r ".[\"org.opencontainers.image.url\"]"`
if [[ $cu == "null" ]]; then
cu="https://podman.io"
fi
fi
fi
support_url=`echo $labels | jq -r ".[\"org.opencontainers.image.documentation\"]"`
if [[ $support_url == "null" ]]; then
support_url="https://podman.io"
fi
sw=`echo $labels | jq -r ".[\"org.opencontainers.image.version\"]"`
if [[ $sw == "null" ]]; then
sw=""
fi
if [[ $registered == false ]]; then
log "Registering device `cwords $name`"
local dev="\"ids\":\"$id\", \"name\":\"`cwords $name`\",\"cu\":\"$cu\",\"mf\":\"podman2mqtt\",\"sw\":\"$sw\""
local o="\"name\":\"podman2mqtt\",\"url\":\"$support_url\",\"sw\":\"$sw\""
local state_cmp="\"state\":{\"name\":\"State\",\"p\":\"binary_sensor\",\"dev_cla\":\"running\",\"uniq_id\":\"sensors.podman.$name.state\",\"def_ent_id\":\"sensors.podman.$name.state\",\"val_tpl\":\"{{ 'ON' if value_json.State == 'running' else 'OFF' }}\",\"json_attr_t\":\"$HOSTNAME/podman/$name/data\",\"ic\":\"mdi:run\"}"
local create_cmp="\"createdAt\":{\"name\":\"createdAt\",\"p\":\"sensor\",\"uniq_id\":\"sensors.podman.$name.createdat\",\"def_ent_id\":\"sensors.podman.$name.createdat\",\"val_tpl\":\"{{ as_datetime(value_json.Created|int).isoformat() }}\",\"dev_cla\":\"timestamp\",\"ic\":\"mdi:calendar\"}"
local start_cmp="\"startedAt\":{\"name\":\"startedAt\",\"p\":\"sensor\",\"dev_cla\":\"timestamp\",\"uniq_id\":\"sensors.podman.$name.startedat\",\"def_ent_id\":\"sensors.podman.$name.startedat\",\"val_tpl\":\"{{ as_datetime(value_json.StartedAt|int).isoformat() }}\",\"ic\":\"mdi:calendar\"}"
mosquitto_pub -r -t "homeassistant/device/podman/$name/config" -m "{\"dev\":{$dev}, \"o\":{$o}, \"cmps\":{$state_cmp, $create_cmp, $start_cmp}, \"stat_t\":\"$HOSTNAME/podman/$name/data\", \"qos\":2}" --insecure
registered_containers+=("$name")
fi
mosquitto_pub -r -t "$HOSTNAME/podman/$name/state" -m "$state" --insecure &
mosquitto_pub -r -t "$HOSTNAME/podman/$name/createdAt" -m "$createdAt" --insecure &
mosquitto_pub -r -t "$HOSTNAME/podman/$name/startedAt" -m "$startedAt" --insecure &
mosquitto_pub -r -t "$HOSTNAME/podman/$name/data" -m "$data" --insecure &
mosquitto_pub -r -t "$HOSTNAME/podman/$name/status" -m "$status_str" --insecure &
done
for item in "${registered_containers[@]}"; do
local running=`contains $item "${running_containers[@]}"`
if [[ $running == false ]]; then
mosquitto_pub -r -t "$HOSTNAME/podman/$item/state" -m "exited" --insecure &
mosquitto_pub -r -t "$HOSTNAME/podman/$item/createdAt" -m "" --insecure &
mosquitto_pub -r -t "$HOSTNAME/podman/$item/startedAt" -m "" --insecure &
mosquitto_pub -r -t "$HOSTNAME/podman/$item/data" -m "{\"State\":\"exited\"}" --insecure &
mosquitto_pub -r -t "$HOSTNAME/podman/$item/status" -m "Not launched" --insecure &
fi
done
log "${#running_containers[@]}/${#registered_containers[@]} running containers"
fi
mosquitto_pub -r -t "$HOSTNAME/podman/state" -m "{\"state\":\"$podman_state\", \"registered\":\"${#registered_containers[@]} \", \"running\":\"${#running_containers[@]}\"}" --insecure &
sleep 120
done
}
LOCK_FILE=/tmp/podman2mqtt-$UID
lockfile-create --retry 0 --use-pid $LOCK_FILE || exit
trap onexit EXIT INT TERM KILL QUIT HUP
main
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment