I’m writing a script to get cake-autorate data into Home Assistant. So far I have the below as proof of concept. Works, but owing to the way procd handles backgrounded processes and ignores SIGPIPE, not all the tail, awk and mosquitto_pub processes are killed after the service is stopped.
Any suggestions? I’m open to abandoning procd.
#!/bin/sh /etc/rc.common
USE_PROCD=1
START=98
STOP=10
LOG_FILE="/var/log/cake-autorate.primary.log"
MQTT_HOST="192.168.x.x"
MQTT_PORT="1883"
MQTT_USER=""
MQTT_PASS=""
MQTT_TOPIC="cake-autorate"
DISC_PREFIX="homeassistant"
DEVICE_ID="openwrt"
DEVICE_NAME="OpenWrt"
MIN_INTERVAL_S=5
publish_sensor () {
mosquitto_pub -h "$MQTT_HOST" -p "$MQTT_PORT" -u "$MQTT_USER" -P "$MQTT_PASS" -r -q 1 \
-t "$DISC_PREFIX/sensor/$DEVICE_ID/$1/config" -m "$2"
}
publish_discovery() {
publish_sensor "dl_achieved_rate_kbps" \
'{"name":"CAKE DL Achieved Rate","state_topic":"cake-autorate","value_template":"{{ value_json.dl_achieved_rate_kbps }}","unit_of_measurement":"kbps","state_class":"measurement","unique_id":"openwrt_dl_achieved_rate","device":{"identifiers":["openwrt"],"name":"OpenWrt"}}'
publish_sensor "ul_achieved_rate_kbps" \
'{"name":"CAKE UL Achieved Rate","state_topic":"cake-autorate","value_template":"{{ value_json.ul_achieved_rate_kbps }}","unit_of_measurement":"kbps","state_class":"measurement","unique_id":"openwrt_ul_achieved_rate","device":{"identifiers":["openwrt"],"name":"OpenWrt"}}'
publish_sensor "cake_dl_rate_kbps" \
'{"name":"CAKE DL Rate","state_topic":"cake-autorate","value_template":"{{ value_json.cake_dl_rate_kbps }}","unit_of_measurement":"kbps","state_class":"measurement","unique_id":"openwrt_cake_dl_rate","device":{"identifiers":["openwrt"],"name":"OpenWrt"}}'
publish_sensor "cake_ul_rate_kbps" \
'{"name":"CAKE UL Rate","state_topic":"cake-autorate","value_template":"{{ value_json.cake_ul_rate_kbps }}","unit_of_measurement":"kbps","state_class":"measurement","unique_id":"openwrt_cake_ul_rate","device":{"identifiers":["openwrt"],"name":"OpenWrt"}}'
publish_sensor "dl_sum_delays" \
'{"name":"DL Delay Sum","state_topic":"cake-autorate","value_template":"{{ value_json.dl_sum_delays }}","unit_of_measurement":"us","state_class":"measurement","unique_id":"openwrt_dl_delay","device":{"identifiers":["openwrt"],"name":"OpenWrt"}}'
publish_sensor "ul_sum_delays" \
'{"name":"UL Delay Sum","state_topic":"cake-autorate","value_template":"{{ value_json.ul_sum_delays }}","unit_of_measurement":"us","state_class":"measurement","unique_id":"openwrt_ul_delay","device":{"identifiers":["openwrt"],"name":"OpenWrt"}}'
publish_sensor "dl_avg_owd_delta_us" \
'{"name":"DL OWD Delta","state_topic":"cake-autorate","value_template":"{{ value_json.dl_avg_owd_delta_us }}","unit_of_measurement":"us","state_class":"measurement","unique_id":"openwrt_dl_owd","device":{"identifiers":["openwrt"],"name":"OpenWrt"}}'
publish_sensor "ul_avg_owd_delta_us" \
'{"name":"UL OWD Delta","state_topic":"cake-autorate","value_template":"{{ value_json.ul_avg_owd_delta_us }}","unit_of_measurement":"us","state_class":"measurement","unique_id":"openwrt_ul_owd","device":{"identifiers":["openwrt"],"name":"OpenWrt"}}'
publish_sensor "dl_load_condition" \
'{"name":"DL Load Condition","state_topic":"cake-autorate","value_template":"{{ value_json.dl_load_condition }}","unique_id":"openwrt_dl_condition","device":{"identifiers":["openwrt"],"name":"OpenWrt"}}'
publish_sensor "ul_load_condition" \
'{"name":"UL Load Condition","state_topic":"cake-autorate","value_template":"{{ value_json.ul_load_condition }}","unique_id":"openwrt_ul_condition","device":{"identifiers":["openwrt"],"name":"OpenWrt"}}'
for c in 0 1 2; do
publish_sensor "cpu_core$c" \
"{\"name\":\"CPU Core $c\",\"state_topic\":\"cake-autorate\",\"value_template\":\"{{ value_json.cpu_core$c }}\",\"unit_of_measurement\":\"%\",\"state_class\":\"measurement\",\"unique_id\":\"openwrt_cpu_$c\",\"device\":{\"identifiers\":[\"openwrt\"],\"name\":\"OpenWrt\"}}"
done
}
start_service() {
publish_discovery
procd_open_instance
procd_set_param command /bin/sh -c "\
tail -F '$LOG_FILE' 2>/dev/null | \
awk -F'; ' -v min_int=$MIN_INTERVAL_S '\
BEGIN {
last_summary = systime() - min_int
last_cpu = systime() - min_int
}
\$1==\"SUMMARY\" && NF>=13 {
n=systime()
if(n-last_summary>=min_int){
last_summary=n
printf \"{\\\"dl_achieved_rate_kbps\\\":%s,\\\"ul_achieved_rate_kbps\\\":%s,\\\"dl_sum_delays\\\":%s,\\\"ul_sum_delays\\\":%s,\\\"dl_avg_owd_delta_us\\\":%s,\\\"ul_avg_owd_delta_us\\\":%s,\\\"dl_load_condition\\\":\\\"%s\\\",\\\"ul_load_condition\\\":\\\"%s\\\",\\\"cake_dl_rate_kbps\\\":%s,\\\"cake_ul_rate_kbps\\\":%s}\\n\",
(\$4~/^[0-9.]+$/)?\$4:0,
(\$5~/^[0-9.]+$/)?\$5:0,
(\$6~/^[0-9.]+$/)?\$6:0,
(\$7~/^[0-9.]+$/)?\$7:0,
(\$8~/^[0-9.]+$/)?\$8:0,
(\$9~/^[0-9.]+$/)?\$9:0,
(\$10!=\"\"?\$10:\"unknown\"),
(\$11!=\"\"?\$11:\"unknown\"),
(\$12~/^[0-9.]+$/)?\$12:0,
(\$13~/^[0-9.]+$/)?\$13:0
}
}
\$1==\"CPU\" && NF>=7 {
n=systime()
if(n-last_cpu>=min_int){
last_cpu=n
printf \"{\\\"cpu_core0\\\":%s,\\\"cpu_core1\\\":%s,\\\"cpu_core2\\\":%s}\\n\",
(\$5~/^[0-9.]+$/)?\$5:0,
(\$6~/^[0-9.]+$/)?\$6:0,
(\$7~/^[0-9.]+$/)?\$7:0
}
}
' | \
mosquitto_pub -h '$MQTT_HOST' -p '$MQTT_PORT' -u '$MQTT_USER' -P '$MQTT_PASS' -t '$MQTT_TOPIC' -l -q 0 -r
"
procd_set_param respawn 3600 5 5
procd_close_instance
}
stop_service(){ :; }
reload_service(){ stop; start; }