作为一名嵌入式开发工程师,我最近在项目中遇到了一个实际需求:如何在不依赖运营商短信服务的情况下,实现短信的自动转发和通知功能。经过多方调研和测试,最终选择了基于Air780系列4G-Cat.1模组的UART短信转发方案。这个方案最大的优势在于完全不需要消耗流量,也不需要额外焊接或复杂的硬件改造,使用现成的开发板就能快速部署。
这个开源项目本质上是一个软硬件结合的解决方案,硬件部分采用合宙通信的Air780系列模组(如Air780EHV、Air780EHM等),软件部分则使用Golang开发的上位机服务。整套系统的工作流程非常清晰:4G模组接收短信后,通过UART串口将短信内容传输给上位机,上位机再根据配置将短信转发到指定的通知渠道(如钉钉、企业微信、飞书等)。
提示:选择Air780系列模组的一个重要原因是其出色的低功耗特性,实测待机电流可以控制在5mA以下,非常适合7×24小时运行的场景。
项目使用的Air780系列模组是基于紫光展锐UIS8910DM芯片的Cat.1 bis模组,支持LTE-FDD/LTE-TDD制式。与传统的GSM模组相比,Cat.1模组在网络覆盖和传输速率上都有明显优势,特别是在2G/3G退网的背景下,Cat.1成为了物联网短信应用的最佳选择。
硬件连接方案有两种:
对于大多数用户来说,我强烈推荐第一种方案,因为开发板已经集成了USB转UART芯片、SIM卡座和必要的电源管理电路,到手即用。以下是开发板的典型接口定义:
code复制USB Type-C接口:
- VBUS:5V电源输入
- D+/D-:USB数据线
- GND:地线
UART接口(排针):
- TXD:模组发送端(连接上位机RXD)
- RXD:模组接收端(连接上位机TXD)
- GND:信号地
在实际部署时,需要注意以下几个关键点:
天线选择:虽然模组内置了PCB天线,但在信号较弱的区域,建议外接胶棒天线。天线的接口规格是IPEX一代,中心频率需覆盖Band 1/3/5/8等常用频段。
SIM卡配置:必须使用支持短信功能的物联网卡或普通手机卡。特别注意:
电源管理:虽然开发板可以通过USB供电,但如果需要长期稳定运行,建议:
整个软件系统采用分层设计,主要分为三个部分:
项目使用Golang实现主要逻辑,主要基于以下几个考虑:
对于大多数用户,Docker是最简单的部署方式。以下是具体步骤:
bash复制# 拉取最新镜像
docker pull smsforwarder/sms-gateway:latest
# 创建配置目录
mkdir -p /etc/smsforwarder/config
# 准备配置文件
cat > /etc/smsforwarder/config/config.yaml <<EOF
serial:
port: /dev/ttyUSB0
baudrate: 115200
notify:
dingtalk:
webhook: "https://oapi.dingtalk.com/robot/send?access_token=YOUR_TOKEN"
wecom:
corp_id: "YOUR_CORP_ID"
agent_id: 1000002
corp_secret: "YOUR_SECRET"
EOF
# 启动容器
docker run -d \
--name sms-forwarder \
--restart always \
--device=/dev/ttyUSB0 \
-v /etc/smsforwarder/config:/app/config \
smsforwarder/sms-gateway:latest
如果需要更灵活的定制,可以选择原生安装:
bash复制# 安装依赖
sudo apt install -y build-essential libudev-dev
# 获取源码
git clone https://github.com/smsforwarder/sms-gateway.git
cd sms-gateway
# 编译
make build
# 安装
sudo cp bin/sms-gateway /usr/local/bin/
sudo cp configs/sms-gateway.service /etc/systemd/system/
# 启动服务
sudo systemctl enable sms-gateway
sudo systemctl start sms-gateway
项目的配置文件采用YAML格式,主要包含以下几个关键部分:
yaml复制serial:
port: /dev/ttyACM0 # 串口设备路径
baudrate: 115200 # 波特率
timeout: 5s # 读写超时
database:
path: "./data/sms.db" # SQLite数据库路径
notify:
email:
enabled: true
smtp_host: "smtp.example.com"
smtp_port: 587
username: "user@example.com"
password: "your_password"
from: "sms@example.com"
to: ["admin@example.com"]
webhook:
- url: "https://api.example.com/sms"
method: "POST"
headers:
Content-Type: "application/json"
template: |
{
"phone": "{{.Phone}}",
"content": "{{.Content}}",
"time": "{{.Time}}"
}
在实际应用中,我们经常需要过滤垃圾短信或只关注特定号码的短信。项目支持基于正则表达式的过滤规则:
yaml复制filters:
- pattern: "^【银行】" # 匹配银行通知
action: "notify" # 触发通知
channels: ["dingtalk", "email"]
- pattern: "验证码"
action: "record" # 仅记录不通知
- pattern: "^1069\d+"
action: "block" # 屏蔽营销短信
通过cron表达式可以配置定时发送短信的功能,特别适合需要定期上报的场景:
yaml复制schedules:
- name: "daily_report"
cron: "0 9 * * *" # 每天9点执行
phone: "13800138000"
message: "系统运行正常,今日已启动"
- name: "weekly_backup"
cron: "0 18 * * 5" # 每周五18点执行
phone: "13900139000"
message: "请确认本周数据备份是否完成"
症状:上位机无法检测到串口设备
排查步骤:
lsusb命令查看设备是否被识别dmesg | grep tty查看串口设备注册情况解决方案:
bash复制# 添加用户到dialout组
sudo usermod -aG dialout $USER
# 查看串口设备权限
ls -l /dev/ttyUSB*
# 临时修改权限
sudo chmod 666 /dev/ttyUSB0
症状:能检测到信号但收不到短信
排查流程:
bash复制echo -e "AT+CSQ\r\n" > /dev/ttyUSB0 # 检查信号强度
echo -e "AT+CMGF=1\r\n" > /dev/ttyUSB0 # 设置为文本模式
echo -e "AT+CNMI=2,2,0,0,0\r\n" > /dev/ttyUSB0 # 设置短信通知方式
对于高并发场景,建议进行以下优化:
串口读写优化:
数据库优化:
网络通知优化:
在工业环境中,可以将该系统与PLC等设备结合,实现:
典型配置示例:
yaml复制industrial:
plc_monitor:
enabled: true
modbus_rtu: "/dev/ttyS0"
baudrate: 9600
parity: "E"
alerts:
- register: 40001
name: "temperature"
threshold: 80
message: "温度过高!当前值:{{.Value}}℃"
通过与Home Assistant等平台对接,可以实现:
集成方法:
yaml复制homeassistant:
url: "http://ha.local:8123/api/webhook/sms_notify"
token: "YOUR_HA_TOKEN"
events:
- pattern: "门禁开锁"
action: "trigger_ha_event"
event_type: "door_unlocked"
经过三个月的实际使用,这套系统在稳定性方面表现非常出色,平均无故障运行时间超过60天。最令我满意的是它的资源占用极低,在树莓派Zero上运行时内存占用不到50MB,CPU利用率长期低于5%。对于需要可靠短信转发功能的场景,这绝对是一个值得考虑的解决方案。