#!/command/with-contenv bashio # shellcheck shell=bash # ============================================================================== # Start mqtt service for disk only # ============================================================================== readonly MAX_TIMEFRAME=60 readonly MIN_TIMEFRAME=10 readonly AVG_TIMEFRAME=$(((MAX_TIMEFRAME + MIN_TIMEFRAME) / 2)) if bashio::config.true "mqtt_nexgen_entities"; then exec sleep infinity fi if [ -f /root/.config/mosquitto_pub ]; then bashio::log.info "Starting the MQTT daemon for disks info..." # Send autodiscovery entities topic=$(bashio::config 'mqtt_topic') if [ "$topic" = "null" ]; then topic="sambanas"; fi # Send discovery messages. if ! bashio::config.true "autodiscovery.disable_persistent"; then prs="-r"; fi jdevice=$(jq -r -c -n --arg topic "$topic" --arg smbv "$(smbd -V | sed s/Version\ //)" --arg addon "$(bashio::addon.version)" ' {device:{ identifiers:[], name: "SambaNas Physical Disk ", hw_version: $addon, sw_version: $smbv, model: "SambaNas", manufacturer: "@Dianlight", via_device: $topic }}') device_scan=$(smartctl --scan-open) if [ -z "$device_scan" ]; then bashio::log.warning "No disk with S.M.A.R.T support found. Disable sensor report" exec sleep infinity fi while read -r -a device; do row=$(smartctl -A -l error -l selftest "${device[0]}" -j | jq '. * (.ata_smart_attributes.table // [] | INDEX(.name)) | del(.ata_smart_attributes.table)') #bashio::log.info "2.2 ${row}" for entity in device.name device.type device.protocol power_on_time.hours power_cycle_count temperature.current \ Raw_Read_Error_Rate.raw.value Reallocated_Sector_Ct.raw.value Wear_Leveling_Count.raw.value UDMA_CRC_Error_Count.raw.value \ ata_smart_error_log.summary.count ata_smart_self_test_log.standard.count; do if [[ -z $(jq ".$entity // empty" <<<"$row") ]]; then # bashio::log.info "2.2 Missing ${entity} in ${row}" continue fi exmsg={} etype="" base=$(jq --arg topic "$topic" --arg entity "$entity" ' { name:($topic+" "+$entity +" "+.device.info_name), unique_id:((.device.name | explode | join("")) + "-" + ($entity|explode|join(""))), value_template:("{{ value_json." +$entity+ "}}"), state_topic:($topic + "/" + (.device.name | gsub("[^A-z]";"")) + "/state" ), oth:{ uuid:.device.name | explode | join(""), label:.device.name } }' <<<"$row") case "$entity" in device.name | device.type | device.protocol) #TEXT etype="sensor" exmsg=$(jq --arg topic "$topic" --arg entity "$entity" ' { mode: "text", icon:"mdi:harddisk" }' <<<"$row") ;; power_on_time.hours) #Time etype="sensor" exmsg=$(jq --arg topic "$topic" --arg entity "$entity" ' { unit_of_measurement: "h", device_class: "duration" }' <<<"$row") ;; power_cycle_count) #number etype="sensor" exmsg=$(jq --arg topic "$topic" --arg entity "$entity" ' { _unit_of_measurement: "", icon:"mdi:power-cycle" }' <<<"$row") ;; Raw_Read_Error_Rate.raw.value | Reallocated_Sector_Ct.raw.value | Wear_Leveling_Count.raw.value | UDMA_CRC_Error_Count.raw.value | ata_smart_error_log.summary.count | ata_smart_self_test_log.standard.count) #number etype="sensor" exmsg=$(jq --arg topic "$topic" --arg entity "$entity" ' { _unit_of_measurement: "", icon:"mdi:chart-box-outline" }' <<<"$row") ;; temperature.current) #temperature etype="sensor" exmsg=$(jq --arg topic "$topic" --arg entity "$entity" ' { unit_of_measurement: "°C", device_class: "temperature", _icon:"mdi:thermometer" }' <<<"$row") ;; *) bashio::log.warning "Autodiscovery for $entity missing!" ;; esac #bashio::log.info "2.4 $base $exmsg" msg=$(echo "$base" "$jdevice" "$exmsg" | jq -s 'add|.device.identifiers[.device.identifiers|length]=.oth.uuid|.device.name=(.device.name + .oth.label)|del(.oth)') #bashio::log.debug "$msg" mosquitto_pub "${prs}" -t "homeassistant/${etype}/${topic}/$(jq -r '.device.name | explode | join("")' <<<$row)-${entity//[\.\/]/-}/config" -m "$msg" done # bashio::log.info "2.3" done <<<"${device_scan}" while read -r -a device; do mkfifo /tmp/mqtt-hanlder-${device[0]//\//} # Send status message process tail -F /tmp/mqtt-hanlder-${device[0]//\//} | mosquitto_pub -l -t "${topic}/${device[0]//\//}/state" & done <<<"${device_scan}" while read -r -a device; do cdevice=${device[0]//\//} shaOldMessage="-" sleepTime=$AVG_TIMEFRAME while true; do #bashio::log.info "[$cdevice] ${shaOldMessage} $sleepTime" status=$(smartctl -A -l error -l selftest "${device[0]}" -j | jq -c '. * (.ata_smart_attributes.table // [] | INDEX(.name)) | del(.ata_smart_attributes.table) | del(.local_time) | del(.smartctl) | del (.json_format_version)') # Debug shaMessage=$(sha1sum <<<"$status") # bashio::log.green "[$cdevice] SleepTimes: $sleepTime $shaOldMessage] ${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-$cdevice shaOldMessage=$shaMessage # Sleep sleep ${sleepTime} done & sleep $((10 / $(wc -l <<<"$device_scan"))) done <<<"${device_scan}" wait else exec sleep infinity fi