feat: 新增 485 的解析

This commit is contained in:
yarnom 2025-08-07 19:14:36 +08:00
parent 26b261a663
commit 89fc15b5c4
3 changed files with 185 additions and 3 deletions

123
export/export.sh Normal file
View File

@ -0,0 +1,123 @@
#!/bin/bash
# 设置环境变量
export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
export LANG=en_US.UTF-8
export LC_ALL=en_US.UTF-8
# 设置PostgreSQL环境变量
export PGPASSWORD="你的密码" # 替换为实际的密码
# 设置数据库连接参数
DB_HOST="localhost"
DB_PORT="5432"
DB_NAME="weatherdb"
DB_USER="yarnom"
EXPORT_DIR="/home/yarnom/Archive/code/WeatherStation/exportData"
# 添加日志功能
LOG_FILE="$EXPORT_DIR/export.log"
# 记录开始时间
echo "=== 开始导出: $(date) ===" >> "$LOG_FILE"
# 确保导出目录存在
mkdir -p "$EXPORT_DIR/data"
# 获取当前时间和10分钟前的时间
CURRENT_DATE=$(date +"%Y-%m-%d")
END_TIME=$(date +"%Y-%m-%d %H:%M:00")
START_TIME=$(date -d "10 minutes ago" +"%Y-%m-%d %H:%M:00")
# 记录时间范围
echo "导出时间范围: $START_TIME$END_TIME" >> "$LOG_FILE"
# 设置当天的数据文件
CURRENT_FILE="$EXPORT_DIR/data/weather_data_${CURRENT_DATE}.csv"
LAST_EXPORT_TIME_FILE="$EXPORT_DIR/last_export_time"
# 检查是否需要创建新文件(新的一天)
if [ -f "$LAST_EXPORT_TIME_FILE" ]; then
LAST_DATE=$(head -n 1 "$LAST_EXPORT_TIME_FILE" | cut -d' ' -f1)
if [ "$LAST_DATE" != "$CURRENT_DATE" ]; then
# 新的一天,将昨天的文件压缩存档
YESTERDAY=$(date -d "yesterday" +"%Y-%m-%d")
if [ -f "$EXPORT_DIR/data/weather_data_${YESTERDAY}.csv" ]; then
gzip "$EXPORT_DIR/data/weather_data_${YESTERDAY}.csv"
fi
fi
fi
# 如果是新文件,创建表头
if [ ! -f "$CURRENT_FILE" ]; then
echo "创建新文件: $CURRENT_FILE" >> "$LOG_FILE"
echo "latitude,longitude,station_id,station_name,date_time,elevation,pressure,temperature,dewpoint,wind_speed,wind_direction,relative_humidity,ztd,pwv" > "$CURRENT_FILE"
fi
# 导出新数据并追加到当天的文件
psql -h "$DB_HOST" -p "$DB_PORT" -d "$DB_NAME" -U "$DB_USER" -A -F "," -t -c "
WITH avg_data AS (
SELECT
s.station_id,
COALESCE(s.password, s.station_id) as output_station_id, -- 如果password为空则使用station_id
'$END_TIME'::timestamp as date_time,
-- 气压、温度取平均
ROUND(AVG(r.pressure)::numeric, 2) as pressure,
ROUND(AVG(r.temperature)::numeric, 2) as temperature,
-- 风速取平均
ROUND(AVG(r.wind_speed)::numeric, 2) as wind_speed,
-- 风向使用矢量平均
ROUND(DEGREES(ATAN2(
AVG(SIN(RADIANS(r.wind_direction))),
AVG(COS(RADIANS(r.wind_direction)))
))::numeric + CASE
WHEN DEGREES(ATAN2(
AVG(SIN(RADIANS(r.wind_direction))),
AVG(COS(RADIANS(r.wind_direction)))
)) < 0 THEN 360
ELSE 0
END, 2) as wind_direction,
-- 湿度取平均
ROUND(AVG(r.humidity)::numeric, 2) as relative_humidity
FROM stations s
JOIN rs485_weather_data r ON s.station_id = r.station_id
WHERE r.timestamp >= '$START_TIME' AND r.timestamp < '$END_TIME'
GROUP BY s.station_id, s.password
)
SELECT
'0', -- latitude
'0', -- longitude
output_station_id, -- station_id (使用password字段)
'', -- station_name
date_time, -- date_time
'0', -- elevation
COALESCE(pressure::text, '0'),
COALESCE(temperature::text, '0'),
'0', -- dewpoint
COALESCE(wind_speed::text, '0'),
COALESCE(wind_direction::text, '0'),
COALESCE(relative_humidity::text, '0'),
'', -- ztd
'' -- pwv
FROM avg_data
ORDER BY output_station_id;" >> "$CURRENT_FILE" 2>> "$LOG_FILE"
# 检查psql执行状态
if [ $? -eq 0 ]; then
echo "数据导出成功" >> "$LOG_FILE"
else
echo "数据导出失败" >> "$LOG_FILE"
fi
# 更新最后导出时间
echo "$END_TIME" > "$LAST_EXPORT_TIME_FILE"
# 记录结束时间
echo "=== 结束导出: $(date) ===" >> "$LOG_FILE"
echo "" >> "$LOG_FILE"
# 保持日志文件大小合理保留最后1000行
tail -n 1000 "$LOG_FILE" > "${LOG_FILE}.tmp" && mv "${LOG_FILE}.tmp" "$LOG_FILE"
# 清除密码环境变量(安全考虑)
unset PGPASSWORD

60
export/get.sh Normal file
View File

@ -0,0 +1,60 @@
#!/bin/bash
# 设置远程服务器信息
REMOTE_USER="root"
REMOTE_HOST="8.134.185.53"
REMOTE_PORT="30001"
REMOTE_PATH="/root/rain/weather-station/dataTransfer/data/"
LOCAL_PATH="/home/imdroid/Build_WRF/cycling_data" # 使用当前目录
LOG_FILE="${LOCAL_PATH}/sync.log"
# 确保本地目录存在
mkdir -p "$LOCAL_PATH"
# 记录开始时间
echo "=== 开始同步: $(date) ===" >> "$LOG_FILE"
# 使用rsync进行增量同步
# -a: 归档模式,保持所有文件属性
# -v: 详细输出
# -z: 传输时压缩数据
# -t: 保持时间戳
# -P: 显示进度并允许断点续传
# -e: 指定ssh命令和端口
# --delete: 删除目标目录中源目录没有的文件
# --timeout=60: 设置超时时间
# --bwlimit=1000: 限制带宽KB/s
rsync -avzt \
-P \
-e "ssh -p ${REMOTE_PORT}" \
--delete \
--timeout=60 \
--bwlimit=1000 \
--include="*.csv" \
--include="*.gz" \
--exclude="*" \
--log-file="$LOG_FILE" \
"${REMOTE_USER}@${REMOTE_HOST}:${REMOTE_PATH}" \
"${LOCAL_PATH}/"
# 检查rsync退出状态
if [ $? -eq 0 ]; then
echo "同步成功完成" >> "$LOG_FILE"
# 检查是否有新文件同步
NEW_FILES=$(find "${LOCAL_PATH}" -type f -mmin -10 \( -name "*.csv" -o -name "*.gz" \))
if [ ! -z "$NEW_FILES" ]; then
echo "新同步的文件:" >> "$LOG_FILE"
echo "$NEW_FILES" >> "$LOG_FILE"
fi
else
echo "同步失败,错误代码: $?" >> "$LOG_FILE"
# 可以在这里添加告警通知(如发送邮件)
fi
# 记录同步时间
echo "=== 结束同步: $(date) ===" >> "$LOG_FILE"
echo "" >> "$LOG_FILE"
# 保持日志文件大小合理保留最后1000行
tail -n 1000 "$LOG_FILE" > "${LOG_FILE}.tmp" && mv "${LOG_FILE}.tmp" "$LOG_FILE"

View File

@ -128,9 +128,8 @@ func startUDP() {
asciiDump := asciiDump(rawData)
log.Printf("ASCII码:\n%s", asciiDump)
// 检查数据是否为RS485格式
if len(rawData) == 25 && rawData[0] == 0x24 {
log.Println("=== 检测到RS485设备数据 ===")
log.Println("485 型气象站数据")
// 生成源码字符串(用于日志记录)
sourceHex := strings.ReplaceAll(strings.TrimSpace(hexDump), "\n", " ")
@ -160,7 +159,7 @@ func startUDP() {
rs485Data.RawDataHex = sourceHex
// 打印解析结果到日志
log.Println("=== RS485解析结果 ===")
log.Println("=== RS485 ===")
log.Printf("设备ID: RS485-%s", rs485Data.DeviceID)
log.Printf("温度: %.2f°C", rs485Data.Temperature)
log.Printf("湿度: %.1f%%", rs485Data.Humidity)