#!/usr/bin/with-contenv bashio # shellcheck shell=bash FAH_API="http://localhost:7396/api" POLL_INTERVAL=30 STATE_TOPIC="foldingathome/state" DISCOVERY_PREFIX="homeassistant" # Abort cleanly if MQTT service is not available if ! bashio::services.mqtt; then bashio::log.info "MQTT not available — skipping sensor publishing. Install the Mosquitto broker add-on to enable HA sensors." exec sleep infinity fi MQTT_HOST=$(bashio::services.mqtt 'host') MQTT_PORT=$(bashio::services.mqtt 'port') MQTT_USER=$(bashio::services.mqtt 'username') MQTT_PASS=$(bashio::services.mqtt 'password') UNIQUE_ID="foldingathome_$(hostname | tr -cd '[:alnum:]_')" mqtt_publish() { mosquitto_pub \ -h "$MQTT_HOST" -p "$MQTT_PORT" \ -u "$MQTT_USER" -P "$MQTT_PASS" \ -t "$1" -m "$2" -r -q 1 } publish_discovery() { local device device=$(jq -n \ --arg id "$UNIQUE_ID" \ '{identifiers: [$id], name: "Folding@home", model: "FAH 8", manufacturer: "foldingathome.org"}') declare -A sensors sensors=( ["status"]='{"name":"Folding@home Status","value_template":"{{ value_json.status }}","icon":"mdi:dna"}' ["ppd"]='{"name":"Folding@home PPD","value_template":"{{ value_json.ppd }}","unit_of_measurement":"PPD","icon":"mdi:speedometer","state_class":"measurement"}' ["progress"]='{"name":"Folding@home Progress","value_template":"{{ value_json.progress }}","unit_of_measurement":"%","icon":"mdi:progress-clock","state_class":"measurement"}' ["credit"]='{"name":"Folding@home Credit","value_template":"{{ value_json.credit }}","unit_of_measurement":"points","icon":"mdi:star","state_class":"total_increasing"}' ) for key in "${!sensors[@]}"; do local config config=$(echo "${sensors[$key]}" | jq \ --arg uid "${UNIQUE_ID}_${key}" \ --arg topic "$STATE_TOPIC" \ --argjson device "$device" \ '. + {unique_id: $uid, state_topic: $topic, device: $device}') mqtt_publish "${DISCOVERY_PREFIX}/sensor/${UNIQUE_ID}_${key}/config" "$config" done bashio::log.info "HA sensor discovery published (${#sensors[@]} sensors)" } # Wait for FAH API to become ready bashio::log.info "Waiting for Folding@home API on port 7396..." until curl -sf "${FAH_API}/info" > /dev/null 2>&1; do sleep 5 done bashio::log.info "Folding@home API ready — starting MQTT sensor publisher" publish_discovery while true; do UNITS=$(curl -sf "${FAH_API}/units" 2>/dev/null || echo "[]") UNIT_COUNT=$(echo "$UNITS" | jq 'length') if [ "$UNIT_COUNT" -gt 0 ]; then RAW_STATE=$(echo "$UNITS" | jq -r '.[0].state // "unknown"') case "$RAW_STATE" in RUN) STATUS="Running" ;; PAUSE) STATUS="Paused" ;; FINISH) STATUS="Finishing" ;; ASSIGN) STATUS="Assigning" ;; DOWNLOAD) STATUS="Downloading" ;; SEND) STATUS="Sending" ;; *) STATUS="Idle" ;; esac PPD=$(echo "$UNITS" | jq '[.[].ppd // 0] | add // 0 | round') PROGRESS=$(echo "$UNITS" | jq '.[0].progress // 0 | . * 100 | round') CREDIT=$(echo "$UNITS" | jq '[.[].credit // 0] | add // 0 | round') else STATUS="Idle" PPD=0 PROGRESS=0 CREDIT=0 fi PAYLOAD=$(jq -n \ --arg status "$STATUS" \ --argjson ppd "$PPD" \ --argjson progress "$PROGRESS" \ --argjson credit "$CREDIT" \ '{status: $status, ppd: $ppd, progress: $progress, credit: $credit}') mqtt_publish "$STATE_TOPIC" "$PAYLOAD" sleep "$POLL_INTERVAL" done