Duke Yin's Technology database

OpenWRT 通过MQTT汇报CPU温度 实时网速

目标是发送OpenWRT的CPU温度数据、实时上传下载数据给HomeAssistant。需要准备HomeAssitant的IP地址、MQTT用户名、密码。

连接OpenWRT的SSH,

安装MQTT客户端:

opkg update
opkg install mosquitto-client-nossl

新建一个sh脚本:

touch /root/report_cpu_temp.sh

利用你熟悉的编辑器vi 或nano 对这个文件内容进行编辑:

#!/bin/sh

# ============================================================
# OpenWRT 状态监控
#
# 上报:
#   CPU 温度
#   WAN 下载速度
#   WAN 上传速度
#
# MQTT Topic:
#   openwrt/cpu_temp
#
# JSON:
#   {
#       "temperature": 52.3,
#       "download": 3.75,
#       "upload": 0.51
#   }
# ============================================================


# -----------------------------
# 配置
# -----------------------------

MQTT_HOST="192.168.2.123"
MQTT_PORT="1883"
MQTT_USER="duke"
MQTT_PASS="As252130"

# 实际互联网流量所在接口
WAN_INTERFACE="wan"

# 流量采样时间,单位:秒
SAMPLE_INTERVAL=1

# MQTT Topic
MQTT_TOPIC="openwrt/cpu_temp"


# -----------------------------
# 检查必要命令
# -----------------------------

if ! command -v mosquitto_pub >/dev/null 2>&1; then
    echo "ERROR: mosquitto_pub command not found" >&2
    exit 1
fi


# -----------------------------
# 检查 WAN 接口
# -----------------------------

WAN_PATH="/sys/class/net/$WAN_INTERFACE"

if [ ! -d "$WAN_PATH" ]; then
    echo "ERROR: network interface '$WAN_INTERFACE' not found" >&2
    exit 1
fi


RX_FILE="$WAN_PATH/statistics/rx_bytes"
TX_FILE="$WAN_PATH/statistics/tx_bytes"

if [ ! -r "$RX_FILE" ]; then
    echo "ERROR: cannot read $RX_FILE" >&2
    exit 1
fi

if [ ! -r "$TX_FILE" ]; then
    echo "ERROR: cannot read $TX_FILE" >&2
    exit 1
fi


# -----------------------------
# 获取 CPU 温度
# -----------------------------

TEMP_FILE="/sys/class/thermal/thermal_zone0/temp"

if [ ! -r "$TEMP_FILE" ]; then
    echo "ERROR: CPU temperature file not found: $TEMP_FILE" >&2
    exit 1
fi

TEMP_RAW=$(cat "$TEMP_FILE" 2>/dev/null)

case "$TEMP_RAW" in
    ''|*[!0-9]*)
        echo "ERROR: invalid CPU temperature: $TEMP_RAW" >&2
        exit 1
        ;;
esac

# 转换为 °C,保留 1 位小数
TEMP=$(awk "BEGIN {printf \"%.1f\", $TEMP_RAW / 1000}")


# -----------------------------
# 第一次读取流量计数器
# -----------------------------

RX1=$(cat "$RX_FILE" 2>/dev/null)
TX1=$(cat "$TX_FILE" 2>/dev/null)

case "$RX1" in
    ''|*[!0-9]*)
        echo "ERROR: invalid RX counter: $RX1" >&2
        exit 1
        ;;
esac

case "$TX1" in
    ''|*[!0-9]*)
        echo "ERROR: invalid TX counter: $TX1" >&2
        exit 1
        ;;
esac


# -----------------------------
# 等待采样时间
# -----------------------------

sleep "$SAMPLE_INTERVAL"


# -----------------------------
# 第二次读取流量计数器
# -----------------------------

RX2=$(cat "$RX_FILE" 2>/dev/null)
TX2=$(cat "$TX_FILE" 2>/dev/null)

case "$RX2" in
    ''|*[!0-9]*)
        echo "ERROR: invalid RX counter: $RX2" >&2
        exit 1
        ;;
esac

case "$TX2" in
    ''|*[!0-9]*)
        echo "ERROR: invalid TX counter: $TX2" >&2
        exit 1
        ;;
esac


# -----------------------------
# 计算流量
# -----------------------------

# 如果接口重启,计数器可能归零。
# 此时不能计算负数,因此直接将速度设为 0。
if [ "$RX2" -lt "$RX1" ]; then
    RX_SPEED=0
else
    RX_SPEED=$((RX2 - RX1))
fi

if [ "$TX2" -lt "$TX1" ]; then
    TX_SPEED=0
else
    TX_SPEED=$((TX2 - TX1))
fi


# -----------------------------
# B/s → MB/s
#
# 使用十进制:
# 1 MB = 1,000,000 Byte
# -----------------------------

DOWNLOAD=$(awk "BEGIN {printf \"%.2f\", $RX_SPEED / 1000000}")
UPLOAD=$(awk "BEGIN {printf \"%.2f\", $TX_SPEED / 1000000}")


# -----------------------------
# 生成 JSON
# -----------------------------

JSON=$(printf '{"temperature":%s,"download":%s,"upload":%s}' \
    "$TEMP" \
    "$DOWNLOAD" \
    "$UPLOAD")


# -----------------------------
# MQTT 发布
# -----------------------------

if ! mosquitto_pub \
    -h "$MQTT_HOST" \
    -p "$MQTT_PORT" \
    -u "$MQTT_USER" \
    -P "$MQTT_PASS" \
    -r \
    -t "$MQTT_TOPIC" \
    -m "$JSON"
then
    echo "ERROR: MQTT publish failed" >&2
    exit 1
fi


# -----------------------------
# 输出日志
# -----------------------------

echo "CPU: ${TEMP} °C | Download: ${DOWNLOAD} MB/s | Upload: ${UPLOAD} MB/s"

exit 0

其中192.168.2.123是HomeAssistant局域网IP,改成你自己的。

改脚本权限为可执行,然后发送一次,看看HomeAssistant能不能收到:

chmod +x /root/report_cpu_temp.sh

/root/report_cpu_temp.sh

如果正常,就加入定时任务:

crontab -e

每30秒发送一次:

* * * * * /root/report_cpu_temp.sh  > /dev/null 2>&1
* * * * * sleep 30;/root/report_cpu_temp.sh  > /dev/null 2>&1

重启cron:

/etc/init.d/cron restart

在HomeAssistant /homeassistant/configuration.yaml 加入3个自定义传感器,对应这三个数据:

- name: "OpenWrt CPU Temperature"
  unique_id: "openwrt_cpu_temp"
  state_topic: "openwrt/cpu_temp"
  icon: 'mdi:thermometer'
  device_class: temperature
  unit_of_measurement: "°C"
  value_template: "{{ value_json.temperature }}"

- name: "OpenWrt Download Speed"
  unique_id: "openwrt_download_speed"
  state_topic: "openwrt/cpu_temp"
  icon: 'mdi:download-network'
  unit_of_measurement: "MB/s"
  state_class: measurement
  value_template: "{{ value_json.download }}"

- name: "OpenWrt Upload Speed"
  unique_id: "openwrt_upload_speed"
  state_topic: "openwrt/cpu_temp"
  icon: 'mdi:upload-network'
  unit_of_measurement: "MB/s"
  state_class: measurement
  value_template: "{{ value_json.upload }}"

执行一次快速重载,然后就可以直接调用这3个传感器显示数据了

发布评论

评论

标注 * 的为必填项。