Files
HAddons/samba/rootfs/etc/s6-overlay/s6-rc.d/mqtt-handler/run
ai-dev e8681cdead test
2025-10-11 12:14:55 +02:00

178 lines
8.6 KiB
Plaintext

#!/command/with-contenv bashio
# shellcheck shell=bash
# ==============================================================================
# Start mqtt service
# ==============================================================================
readonly MAX_TIMEFRAME=60
readonly MIN_TIMEFRAME=5
readonly AVG_TIMEFRAME=$(((MAX_TIMEFRAME + MIN_TIMEFRAME) / 2))
if [ -f /root/.config/mosquitto_pub ]; then
bashio::log.info "Starting the MQTT daemon for partitions info..."
topic=$(bashio::config 'mqtt_topic' "sambanas")
# Send autodiscovery entities
if bashio::config.true "mqtt_nexgen_entities"; then
bashio::log.info "New MQTT integration"
host=$(bashio::config 'mqtt_host' "$(bashio::services 'mqtt' 'host')")
username=$(bashio::config 'mqtt_username' "$(bashio::services 'mqtt' 'username')")
password=$(bashio::config 'mqtt_password' "$(bashio::services 'mqtt' 'password')")
port=$(bashio::config 'mqtt_port' "$(bashio::services 'mqtt' 'port')")
log_level=$(bashio::string.lower "$(bashio::config log_level info)")
#bashio::log.info "New MQTT config ${host}:${port:-1883} ${username}:${password} ${topic}"
idleparam=""
if [ -p /tmp/hdidle.events ]; then
idleparam="-i /tmp/hdidle.events"
fi
exec /usr/bin/poetry -C /usr/local/bin/ run python /usr/local/bin/mqtt_daemon.py -b "${host}" -p "${port:-1883}" -u "${username}" -P "${password}" -t "${topic}" -v $(bashio::addon.version) ${idleparam} -l ${log_level^^}
else
bashio::log.info "MQTT integration"
# disks=$(awk 'BEGIN { ORS=""; print "["} /^ path = .*/g { printf "%s\"%s\"",separator,$3 ; separator="," } END { print "]" } ' /etc/samba/smb.conf)
disks=$(grep path /etc/samba/smb.conf | sed 's/.*path\ =\ //' | jq --raw-input --slurp 'split("\n") | map(select(. != ""))')
blk=$(lsblk -b -no PARTUUID,NAME,LABEL,FSTYPE,MOUNTPOINTS -J -y)
jdisks=$(jq --argjson disks "$disks" 'reduce (.blockdevices[].children[]? |select(.mountpoints? - $disks != .mountpoints) ) as $i ({};.[$i.name] = $i)' <<<${blk})
# Send discovery messages.
if ! bashio::config.true "autodiscovery.disable_persistent"; then prs="-r"; fi
#bashio::log.info $device
device=$(jq -r -c -n --arg topic "$topic" --arg smbv "$(smbd -V | sed s/Version\ //)" --arg addon "$(bashio::addon.version)" '
{device:{
identifiers:[],
name: "SambaNas Disk ",
hw_version: $addon,
sw_version: $smbv,
model: "SambaNas",
manufacturer: "@Dianlight",
via_device: $topic
}}')
for row in $(jq -r '.|map(.|@base64)|.[]' <<<"$jdisks"); do
for entity in name label mountpoints fssize fsused fsuse_pct fsavail fstype iostat.tps iostat.kB_read/s iostat.kB_wrtn/s iostat.kB_dscd/s iostat.kB_read iostat.kB_wrtn iostat.kB_dscd; do
exmsg={}
etype=""
base=$(jq --arg topic "$topic" --arg entity "$entity" -R '@base64d|fromjson|
{
name:($topic+" "+$entity +" "+ .label),
unique_id:(.partuuid +"-"+ ($entity|explode|join(""))),
value_template:("{{ value_json." + .name + "." +$entity+ "}}"),
state_topic:($topic + "/state"),
oth:{
partuuid:.partuuid,
name:.name,
label:.label,
root:("/dev/" + .name[:-1])
}
}' <<<"$row")
case "$entity" in
name | label | fstype | mountpoints) #TEXT
etype="sensor"
exmsg=$(jq --arg topic "$topic" --arg entity "$entity" -R '@base64d|fromjson|
{
mode: "text",
icon:"mdi:harddisk"
}' <<<"$row")
;;
fssize | fsused | fsavail) #DATA_SIZE (Byte)
etype="sensor"
exmsg=$(jq --arg topic "$topic" --arg entity "$entity" -R '@base64d|fromjson|
{
unit_of_measurement: "B",
device_class: "data_size",
}' <<<"$row")
;;
iostat.kB_read | iostat.kB_wrtn | iostat.kB_dscd) #DATA_SIZE (KB)
etype="sensor"
exmsg=$(jq --arg topic "$topic" --arg entity "$entity" -R '@base64d|fromjson|
{
unit_of_measurement: "kB",
device_class: "data_size",
}' <<<"$row")
;;
iostat.kB_read/s | iostat.kB_wrtn/s | iostat.kB_dscd/s) #data_rate
etype="sensor"
exmsg=$(jq --arg topic "$topic" --arg entityb "${entity%.*}" --arg entityd "${entity##*.}" -R '@base64d|fromjson|
{
unit_of_measurement: "kB/s",
device_class: "data_rate",
value_template:("{{ value_json." + .name + "." +$entityb+ "['"'"'" + $entityd + "'"'"']}}"),
icon:"mdi:database-refresh"
}' <<<"$row")
;;
iostat.tps) #TPS
etype="sensor"
exmsg=$(jq --arg topic "$topic" --arg entity "$entity" -R '@base64d|fromjson|
{
unit_of_measurement: "tps",
icon:"mdi:database-search"
}' <<<"$row")
;;
fsuse_pct) # PERCENT
etype="sensor"
exmsg=$(jq --arg topic "$topic" --arg entity "$entity" -R '@base64d|fromjson|
{
unit_of_measurement: "%",
icon:"mdi:database-eye"
}' <<<"$row")
;;
*)
bashio::log.warning "Autodiscovery for $entity missing!"
;;
esac
msg=$(echo "$base" "$device" "$exmsg" | jq -s 'add|.device.identifiers[.device.identifiers|length]=.oth.partuuid|.device.name=(.device.name + .oth.label)|.device.via_device=(.oth.root | explode | join(""))|del(.oth)')
#bashio::log.debug "$msg"
mosquitto_pub "${prs}" -t "homeassistant/${etype}/${topic}/$(jq -R -r '@base64d|fromjson|.partuuid' <<<"$row")-${entity//[\.\/]/-}/config" -m "$msg"
done
done
mkfifo /tmp/mqtt-hanlder
# Send status message process
tail -F /tmp/mqtt-hanlder | mosquitto_pub -l -t "${topic}/state" &
sleepTime=$AVG_TIMEFRAME
shaOldMessage="-"
while true; do
blk=$(lsblk -b -no NAME,LABEL,FSSIZE,FSUSED,FSUSE%,FSAVAIL,FSTYPE,MOUNTPOINTS -J -y | jq 'walk(if type == "object" and .fsuse_pct != null then .fsuse_pct|=(rtrimstr("%")|tonumber) else . end)')
liostat=$(/usr/bin/iostat "$(jq -r '.|map(.name)|.[]' <<<"""$jdisks""")" -k -d -p -o JSON)
status=$(jq -c --argjson disks "$disks" --argjson iostat "$liostat" 'reduce (.blockdevices[].children[]? |select(.mountpoints? - $disks != .mountpoints) ) as $i ({};.[$i.name] = $i+{iostat:($iostat.sysstat.hosts[0].statistics[0].disk[] | select(.disk_device==$i.name))})' <<<"${blk}")
# Send status message
shaMessage=$(sha1sum <<<"$status")
if [ "$shaOldMessage" = "$shaMessage" ]; then
sleepTime=$((sleepTime * 2))
[ $sleepTime -gt $MAX_TIMEFRAME ] && sleepTime=$MAX_TIMEFRAME
else
# Send status message
if [ $sleepTime -gt $AVG_TIMEFRAME ]; then
sleepTime=$((sleepTime / 2))
else
sleepTime=$((sleepTime - MIN_TIMEFRAME))
fi
[ $sleepTime -le $MIN_TIMEFRAME ] && sleepTime=$MIN_TIMEFRAME
fi
jq -c --arg st "$sleepTime" --arg sh "$shaMessage" '. +
{
ref: {
mws: $st,
sha: $sh
}
}' <<<"${status}" >/tmp/mqtt-hanlder
shaOldMessage=$shaMessage
# Sleep
sleep $sleepTime
done
fi
else
exec sleep infinity
fi