Skip to content

henrydontbbai/CardPulse

Repository files navigation

CardPulse / 卡脉

让每一张 SIM 卡都有跳动的脉搏

License: MIT Shell

简介

CardPulse 是一个轻量级的 SIM 卡保活工具,通过 AT 命令直接控制 4G 模组发送定时短信,实现号码保活功能。

专为 GG 卡 (Google Voice) 等需要定期发送短信以防止号码回收的场景设计。

功能特性

  • 完全独立:无需任何外部服务,直接通过串口控制 4G 模组
  • PDU 短信编码:默认使用 PDU 模式,支持英文、中文和 GSM 扩展字符
  • 定时保号:按设定天数自动发送短信,保持 SIM 卡活跃
  • 智能调度:仅在达到设定天数时发送,避免浪费
  • 状态持久化:记录上次发送时间,重启后继续计时
  • 多渠道通知:支持 Telegram、微信、企业微信、QQ、飞书、钉钉、Bark、Email
  • 自动检测:自动发现串口设备,支持手动配置
  • 完善日志:所有操作记录到日志文件,便于排查
  • CI 与容器化:提供 GitHub Actions、Dockerfile 和本地测试入口

硬件要求

设备 说明
开发板 树莓派 4B/5、x86 工控机或其他 Linux 设备
4G 模组 Quectel EC20/EC25、华为 ME909 等支持 AT 命令的模组
SIM 卡 待保号的 Google Voice 卡或其他 SIM 卡
电源 5V/3A 适配器,24 小时运行

快速开始

1. 安装 CardPulse

# 克隆仓库
git clone https://github.com/henrydontbbai/CardPulse.git
cd CardPulse

# 运行安装脚本
sudo ./scripts/install.sh

2. 配置

编辑配置文件 ~/.cardpulse/config.yaml

# 串口配置
serial:
  port: "/dev/ttyUSB0"
  baudrate: 115200
  auto_detect: true

# 短信配置
sms:
  phone: "+8613800138000"  # 你的 GG 卡号码
  message: "Hello from CardPulse"
  interval_days: 179

3. 验证

# 先做安全硬件诊断(不发短信、不写状态)
cardpulse --doctor

# 查看模组信息
cardpulse --info

# 真实短信测试:仅在确认授权后执行
# cardpulse --test

# 查看状态
cardpulse --status

4. 设置定时任务

安装脚本默认优先配置 systemd timer;如果 systemd 不可用,则回退到 cron(每天凌晨 2 点执行)。

sudo systemctl start cardpulse.timer
sudo systemctl status cardpulse.timer

Docker 使用

docker build -t cardpulse:local .
docker run --rm \
  --device /dev/ttyUSB0 \
  --group-add "$(getent group dialout | cut -d: -f3)" \
  -v "$HOME/.cardpulse:/home/cardpulse/.cardpulse" \
  cardpulse:local --status

容器默认使用非 root 用户 cardpulse 运行。实际发送短信时需要通过 --device 暴露串口设备,并挂载包含 config.yaml 的配置目录。若宿主机串口属于 dialout 组,建议用 --group-add 传入宿主机上的 dialout GID。

当前版本默认走单条 PDU 短信,不做长短信拆分;GSM 7-bit 最多 160 septets,UCS2 最多 140 octets。

macOS 真机测试

macOS 可用于连接 4G 模组做 AT/PDU 真机验证,但不作为生产安装目标。建议先安装依赖:

brew install bash coreutils shellcheck python
python3 -m pip install pyyaml

常见串口为 /dev/cu.usbserial*/dev/cu.usbmodem*/dev/cu.wchusbserial*/dev/cu.SLAB_USBtoUART*。配置时建议关闭自动检测并写入实际端口:

serial:
  port: "/dev/cu.usbserial-XXXX"
  baudrate: 115200
  auto_detect: false

Linux 安装器、systemd、logrotate 和生产调度仍以 Linux 环境验证为准。

命令行选项

用法: cardpulse [选项]

选项:
  -c, --config FILE    指定配置文件路径
  -f, --force          强制发送(忽略间隔检查)
  -s, --status         显示状态信息
  -t, --test           测试发送(不记录状态)
  -i, --info           显示模组信息
  -r, --reset          重置状态(重新开始计时)
  -n, --notify         测试通知功能
  --notify-channel CH  测试指定通知渠道
  --doctor             运行硬件诊断;不发送短信、不写入状态
  -v, --version        显示版本
  -h, --help           显示帮助

通知配置

CardPulse 支持 7 种主流通讯软件通知,在配置文件中启用并填入相应信息即可:

通讯软件 配置项 获取方式
Telegram notify.telegram 创建 Bot
微信 notify.wechat Server酱
企业微信 notify.wecom 群机器人 Webhook
QQ notify.qq Qmsg
飞书 notify.feishu 群自定义机器人 Webhook
钉钉 notify.dingtalk 群自定义机器人 Webhook
Bark notify.bark Bark App
Email notify.email SMTP 服务器配置

项目结构

CardPulse/
├── bin/
│   └── cardpulse                 # 主入口
├── lib/
│   ├── config_reader.sh          # 配置读取
│   ├── at_modem.sh               # AT 命令通信
│   ├── sms_sender.sh             # 短信发送
│   ├── state_manager.sh          # 状态管理
│   ├── notifier.sh               # 通知推送
│   └── pdu_encoder.py            # PDU 编码器
├── config/
│   └── config.example.yaml       # 配置模板
├── scripts/
│   ├── install.sh                # 安装脚本
│   ├── cardpulse.service         # systemd 服务
│   └── cardpulse.timer           # systemd 定时器
├── tests/                        # 本地测试
├── DISCLAIMER.md                 # 法律声明
├── LICENSE                       # MIT 许可证
└── README.md                     # 项目说明

常见问题

Q: 如何运行本地测试?

sudo apt-get install -y python3-yaml shellcheck
bash tests/run.sh

tests/run.sh 会检查 Python 语法、版本一致性、配置 schema、PDU 编码和 Shell 语法。

Q: 如何查看串口设备?

ls /dev/ttyUSB* /dev/ttyACM*

Q: 权限不足怎么办?

# 将用户添加到 dialout 组
sudo usermod -aG dialout $USER

# 重新登录后生效

Q: 如何调试 AT 命令?

# 使用 minicom 连接串口
sudo minicom -D /dev/ttyUSB0 -b 115200

# 关键 AT 命令
AT          # 握手
AT+CSQ      # 查看信号
AT+CREG?    # 查看网络注册
AT+CPIN?    # 查看 SIM 卡状态

Q: GG 卡保号周期是多少天?

Google Voice 要求每 180 天至少有一次活动。CardPulse 默认设置为 179 天,留有余量。

Q: 如何同时保多张卡?

目前 CardPulse 支持单卡。如需多卡,可以部署多个实例,使用不同的配置文件。

免责声明

本工具仅供个人学习与技术研究使用。使用本工具自动化发送短信可能违反 Google Voice 服务条款,导致号码被回收或帐户被封禁。使用风险由使用者自行承担。

详见 DISCLAIMER.md

硬件诊断与 macOS 测试

使用 --info 或发送短信前,先确认 4G 模块暴露了 AT 串口。系统能看到 USB 设备不等于 CardPulse 能使用。

cardpulse --doctor

--doctor 不会发送短信,也不会写入 CardPulse 状态。如果存在 AT 串口,它会发送 AT 等查询命令确认模块是否返回 OK

在 macOS 上,先找 /dev/cu.usbserial*/dev/cu.usbmodem*。如果 DJI/Baiwang 2CA3:4006 只出现在 USB 列表里,但没有 AT 串口,CardPulse 还不能直接使用它。

在 Linux 上,--doctor 还会报告 /dev/cdc-wdm* 这类 MBIM/QMI 控制口。这能解释为什么 VoHive 这类工具可能可用,但不代表 CardPulse 的 AT 串口路径已经就绪。详见 docs/hardware-diagnostics.md

Apple Silicon Mac 可以用 Ubuntu ARM64 虚拟机加 USB 直通验证 DJI 模块;如果 VM 内出现 MBIM/QMI 控制口,再构建 VoHive linux_arm64 做只读发现。不要运行现有 linux_amd64 二进制,也不要在未授权时发送真实短信。

CardPulse Web 控制台

CardPulse 现在提供一个轻量本地 Web 控制台,采用和 VoHive 类似的控制模式:浏览器调用本地 HTTP API,本地后端再调用 CardPulse CLI / AT 串口逻辑,网页本身不直接访问 USB。

python3 scripts/cardpulse-web.py

默认地址为 http://127.0.0.1:8765。在 WSL 中需要从 Windows 浏览器访问时,可以绑定到本地网络接口:

python3 scripts/cardpulse-web.py --host 0.0.0.0 --port 8765

Web 控制台默认只提供状态、诊断、设备信息和只读 AT 查询。真实测试短信默认关闭;如需启用,必须启动时显式加 --allow-sms,并在页面中二次输入 SEND_SMS

Windows + WSL 的 DJI/Baiwang 模块可用一键恢复脚本启动只读控制台:

powershell -ExecutionPolicy Bypass -File scripts/start-dji-wsl-web.ps1

脚本会从 usbipd list 自动查找 DJI/Baiwang 2CA3:4006 的 BusId;只有需要手动覆盖时才传 -BusId。恢复验收会检查 AT、SIM READY、RSSI、网络注册和 Web 健康概览。

详见 docs/web-control.md。 产品定位与下一阶段方向见 docs/product-direction.md

短信接收 / 收件箱

CardPulse 现在提供安全收件箱命令:

cardpulse --sms-status
cardpulse --inbox
cardpulse --read-sms 1
cardpulse --delete-sms 1 --confirm DELETE_SMS

默认行为是只读:--inbox--read-sms 不会删除短信,也不会把短信正文写入 CardPulse 状态文件。读取未读短信时,模块自身可能把该短信标记为已读。

DJI/Baiwang QDC507 已验证支持短信接收相关 AT 查询:AT+CSMS?AT+CPMS?AT+CMGF?AT+CNMI?。如果 --sms-status 显示类似 Storage: ME 23/23 FULL,说明模块短信存储已满,需要先查看收件箱并手动删除无用短信,才能稳定接收新短信。

删除短信必须显式指定单条索引,并提供确认令牌 DELETE_SMS;CardPulse 不提供自动清空或批量删除。

Web 首页通过 /api/overview 汇总设备连接、SIM/网络、短信容量和保号任务,并给出“推荐动作”。收件箱页面仍坚持手动单条删除:只删除明确无用的短信,且必须输入 DELETE_SMS

当前 Windows + WSL + DJI/Baiwang QDC507 路线的日常检查顺序建议为:

cardpulse --doctor
cardpulse --info
cardpulse --sms-status
cardpulse --inbox

如果短信存储显示 ME 23/23 FULL,先读取收件箱并只删除明确无用的一条旧短信,再测试接收新短信。当前实测模块在删除五条旧短信后为 ME 18/23,后续以实时 --sms-status 输出为准。

License

MIT

About

轻量级 SIM 卡定时保号工具,通过 AT 命令直接控制 4G 模组发送短信

Topics

Resources

License

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Packages

 
 
 

Contributors