feat: 简单编写了主脚本和电费提醒功能脚本,目前仅限西海岸能用

This commit is contained in:
2025-12-01 11:08:10 +08:00
parent e99e3ea18c
commit 9959e67a18
2 changed files with 305 additions and 0 deletions
+148
View File
@@ -0,0 +1,148 @@
#!/bin/bash
# ==========================================
# 主控制脚本 (Main Runner)
# 功能:依赖管理、配置生成、任务调度、日志整合
# ==========================================
# --- 1. 路径定义 ---
BASE_DIR=$(cd $(dirname $0); pwd)
SRC_DIR="$BASE_DIR/src"
CONFIG_FILE="$BASE_DIR/config.toml"
LOG_FILE="$BASE_DIR/service.log"
# 日志
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE"
}
trap "log '服务停止'; exit" SIGTERM SIGINT
# 依赖检查和安装
check_and_install_dependencies() {
local dependencies=("curl" "jq" "bc")
local missing_packages=()
for pkg in "${dependencies[@]}"; do
if ! command -v "$pkg" &> /dev/null; then
missing_packages+=("$pkg")
fi
done
if [ ${#missing_packages[@]} -eq 0 ]; then
log "环境检查通过: 依赖已就绪。"
return 0
fi
log "检测到缺失依赖: ${missing_packages[*]},尝试自动安装..."
local install_cmd=""
if command -v apt-get &> /dev/null; then install_cmd="apt-get update && apt-get install -y";
elif command -v yum &> /dev/null; then install_cmd="yum install -y";
elif command -v dnf &> /dev/null; then install_cmd="dnf install -y";
elif command -v apk &> /dev/null; then install_cmd="apk add --no-cache";
else log "无法自动安装,请手动安装: ${missing_packages[*]}"; exit 1; fi
if [ "$EUID" -ne 0 ] && command -v sudo &> /dev/null; then
install_cmd="sudo $install_cmd"
fi
# 这里也将安装日志通过管道传递给 log 函数,保持日志格式统一
eval "$install_cmd ${missing_packages[*]}" 2>&1 | while IFS= read -r line; do
log "[依赖安装] $line"
done
# 二次检查
for pkg in "${missing_packages[@]}"; do
if ! command -v "$pkg" &> /dev/null; then
log "依赖 $pkg 安装失败,请检查网络或源。"
exit 1
fi
done
log "依赖安装完成。"
}
# --- 4. 配置文件生成与检查 ---
check_and_create_config() {
if [ ! -f "$CONFIG_FILE" ]; then
log "配置文件不存在,正在生成默认配置..."
cat > "$CONFIG_FILE" << EOF
# ==========================================
# OUCShell配置文件
# ==========================================
[Global]
# 接收通知的邮箱
TargetEmail = "your_email@example.com"
[SMTP]
# 发件人邮箱服务器配置
Host = "smtp.qq.com"
Port = "465"
User = "your_smtp_email@qq.com"
Password = "your_smtp_auth_code"
# --- 功能模块: 电费提醒 ---
[Electricity]
Enabled = true
Campus = "xha"
# xha = 西海岸
[Electricity.xha]
StudentID = "20230000"
Token = "YOUR_TOKEN_HERE"
# [照明警戒值, 空调警戒值]
RemindTime = [30.0, 30.0]
EOF
log "配置文件已生成: $CONFIG_FILE"
log "检测到第一次加载此脚本,将自动结束本脚本,请前往编辑配置文件"
exit 0
else
log "加载配置文件: $CONFIG_FILE"
fi
}
# 主函数
log "服务启动..."
check_and_install_dependencies
check_and_create_config
# 任务间隔 (秒)
INTERVAL_ELEC=1800 # 半小时
LAST_RUN_ELEC=0
log "进入循环调度模式..."
while true; do
CURRENT_TIME=$(date +%s)
# 电费监控
# 计算时间差
TIME_DIFF=$((CURRENT_TIME - LAST_RUN_ELEC))
if [ $TIME_DIFF -ge $INTERVAL_ELEC ]; then
SCRIPT_PATH="$SRC_DIR/elec_monitor.sh"
if [ -f "$SCRIPT_PATH" ]; then
chmod +x "$SCRIPT_PATH"
log "调度任务: 电费监控..."
/bin/bash "$SCRIPT_PATH" "$CONFIG_FILE" 2>&1 | while IFS= read -r line; do
log "[elec_monitor] $line"
done
log "任务结束: 电费监控"
else
log "警告: 找不到脚本 $SCRIPT_PATH"
fi
LAST_RUN_ELEC=$(date +%s)
fi
# 其他任务(预留)
# TODO
sleep 60
done
+157
View File
@@ -0,0 +1,157 @@
#!/bin/bash
# ==========================================
# 电费提醒功能脚本
# ==========================================
CONFIG_PATH="$1"
# 检查参数
if [ -z "$CONFIG_PATH" ]; then
echo "错误: 未传入配置文件路径。"
exit 1
fi
if [ ! -f "$CONFIG_PATH" ]; then
echo "错误: 配置文件不存在 ($CONFIG_PATH)"
exit 1
fi
# 配置读取
get_val() {
local section=$1
local key=$2
local safe_section=$(echo "$section" | sed 's/\./\\./g')
sed -n "/^\[$safe_section\]/,/^\[/p" "$CONFIG_PATH" \
| grep "^$key" \
| head -n 1 \
| awk -F'=' '{print $2}' \
| tr -d ' "' \
| sed 's/#.*//' \
| tr -d '\r'
}
# 邮件发送函数
send_email() {
local subject=$1
local content=$2
local smtp_host=$(get_val "SMTP" "Host")
local smtp_port=$(get_val "SMTP" "Port")
local smtp_user=$(get_val "SMTP" "User")
local smtp_pass=$(get_val "SMTP" "Password")
local target_email=$(get_val "Global" "TargetEmail")
if [ -z "$smtp_user" ] || [ -z "$target_email" ]; then
echo "错误: 邮箱配置不完整,跳过发送。"
return
fi
echo "正在发送邮件到 $target_email ..."
local curl_url="smtp://$smtp_host:$smtp_port"
if [ "$smtp_port" == "465" ]; then
curl_url="smtps://$smtp_host:$smtp_port"
fi
local mail_data="From: \"电费助手\" <$smtp_user>
To: <$target_email>
Subject: $subject
MIME-Version: 1.0
Content-Type: text/html; charset=utf-8
$content"
echo "$mail_data" | curl --silent --ssl-reqd \
--url "$curl_url" \
--user "$smtp_user:$smtp_pass" \
--mail-from "$smtp_user" \
--mail-rcpt "$target_email" \
--upload-file -
}
# --- 业务逻辑: 西海岸校区 ---
check_xha() {
local sno=$(get_val "Electricity.xha" "StudentID")
local token=$(get_val "Electricity.xha" "Token")
local thresholds_raw=$(get_val "Electricity.xha" "RemindTime" | tr -d '[]' | tr ',' ' ')
local light_limit=$(echo $thresholds_raw | awk '{print $1}')
local ac_limit=$(echo $thresholds_raw | awk '{print $2}')
# 如果解析失败默认设为0
light_limit=${light_limit:-0}
ac_limit=${ac_limit:-0}
if [ -z "$sno" ] || [ -z "$token" ]; then
echo "错误: 学号或Token未配置,请修改 config.toml"
return
fi
echo "查询西海岸校区... (学号: $sno)"
local response=$(curl -s -X POST "http://10.128.13.25/hydxcas/getCadByNo" \
-H "Token: $token" \
-H "Content-Type: application/json" \
-d "{\"sno\": \"$sno\"}")
local errcode=$(echo "$response" | jq -r '.errcode')
if [ "$errcode" != "0" ]; then
echo "API 请求失败: $(echo "$response" | jq -r '.errmsg')"
return
fi
# 解析数据
local light_val=$(echo "$response" | jq -r '.value | fromjson | .eqptData[] | select(.categoryEnergyName == "照明与插座") | .buyElec')
local ac_val=$(echo "$response" | jq -r '.value | fromjson | .eqptData[] | select(.categoryEnergyName == "空调末端") | .buyElec')
light_val=${light_val:-0}
ac_val=${ac_val:-0}
echo "当前电量 -> 照明: $light_val, 空调: $ac_val"
echo "警戒阈值 -> 照明: $light_limit, 空调: $ac_limit"
local need_alert=0
local msg="<h3>电费余额不足提醒</h3><ul>"
# 使用 bc 进行比较,增加 2>/dev/null 屏蔽非数字报错
if (( $(echo "$light_val < $light_limit" | bc -l 2>/dev/null) )); then
need_alert=1
msg="${msg}<li><strong>照明:</strong> ${light_val} 度 (低于 ${light_limit})</li>"
fi
if (( $(echo "$ac_val < $ac_limit" | bc -l 2>/dev/null) )); then
need_alert=1
msg="${msg}<li><strong>空调:</strong> ${ac_val} 度 (低于 ${ac_limit})</li>"
fi
msg="${msg}</ul><p>请及时充值!</p>"
if [ $need_alert -eq 1 ]; then
send_email "【紧急】宿舍电费余额不足" "$msg"
else
echo "电量充足,无需提醒。"
fi
}
# 主函数部分
ENABLED=$(get_val "Electricity" "Enabled")
if [ "$ENABLED" != "true" ]; then
echo "电费监控模块未启用。"
exit 0
fi
CAMPUS=$(get_val "Electricity" "Campus")
case "$CAMPUS" in
"xha")
check_xha
;;
*)
echo "未知的校区配置: $CAMPUS"
;;
esac