如何用Python结合AT命令模拟GSM Modem余额并触发短信发送?
GSM调制解调器模拟余额并关联短信发送解决方案
我想用Python通过GSM调制解调器发送AT命令,模拟或修改调制解调器的余额,让代码识别这个模拟余额后给指定手机号发短信。目前已经实现了短信发送和余额查询功能,但没办法完成余额模拟及关联短信发送的部分。
原代码
# Configure the serial port (replace with your specific port) ser = serial.Serial('COM3', 9600, timeout=1) import serial import time def read_phone_numbers(filename): with open(filename, 'r') as file: phone_numbers = [line.strip() for line in file] return phone_numbers def send_sms(phone_number, message): try: # Send SMS using AT commands ser.write(b'AT\r') time.sleep(1) ser.write(b'AT+CMGF=1\r') # Set SMS mode to text time.sleep(1) ser.write(f'AT+CMGS="{phone_number}"\r'.encode()) time.sleep(1) ser.write(message.encode() + b'\x1A') # Send the message and Ctrl+Z to end time.sleep(1) print(f'SMS sent to {phone_number}') # Read the modem response (optional) response = ser.read(ser.in_waiting).decode('utf-8') print('Modem response:', response) except serial.SerialException as se: print('Serial port exception:', str(se)) except Exception as e: print('Failed to send SMS:', str(e)) finally: # Close the serial port ser.close() # Usage phone_numbers = read_phone_numbers('phone_numbers.txt') message = 'This is a test message from Python using GSM modem.' for phone_number in phone_numbers: send_sms(phone_number, message) # 余额查询代码 import serial import time # Configure the serial port (replace with your specific port) ser = serial.Serial('COM3', 9600, timeout=1) def check_balance(): try: # Send AT command to check balance (hypothetical example) ser.write(b'AT+CUSD=1,"*123#",15\r') time.sleep(1) # Read and print the modem response response = ser.read(ser.in_waiting).decode('utf-8') print('Balance response:', response) except Exception as e: print('Failed to check balance:', str(e)) finally: # Close the serial port ser.close() # Usage check_balance()
核心思路
GSM调制解调器的实际余额由运营商服务器管控,无法通过AT命令直接修改。我们可以在代码层面实现本地模拟余额,替代真实的余额查询结果,然后基于这个模拟余额判断是否执行短信发送操作。
修改后的完整代码
import serial import time # 配置串口(替换为你的实际端口) SERIAL_PORT = 'COM3' BAUD_RATE = 9600 TIMEOUT = 1 # 模拟余额设置 LOCAL_BALANCE = 5.0 # 初始模拟余额,单位:元 SMS_COST = 0.1 # 每条短信的费用 def read_phone_numbers(filename): with open(filename, 'r') as file: phone_numbers = [line.strip() for line in file] return phone_numbers def check_simulated_balance(): """返回模拟余额""" global LOCAL_BALANCE return LOCAL_BALANCE def deduct_balance(): """发送短信后扣除对应费用""" global LOCAL_BALANCE LOCAL_BALANCE -= SMS_COST print(f"已扣除短信费用 {SMS_COST} 元,当前模拟余额: {LOCAL_BALANCE:.2f} 元") def send_sms(ser, phone_number, message): try: # 设置短信模式为文本 ser.write(b'AT+CMGF=1\r') time.sleep(0.5) # 指定接收手机号 ser.write(f'AT+CMGS="{phone_number}"\r'.encode()) time.sleep(0.5) # 发送短信内容+结束符Ctrl+Z ser.write(message.encode() + b'\x1A') time.sleep(1) # 读取调制解调器响应 response = ser.read(ser.in_waiting).decode('utf-8', errors='ignore') if "OK" in response: print(f"SMS成功发送至 {phone_number}") deduct_balance() else: print(f"SMS发送至 {phone_number} 失败,响应: {response}") except serial.SerialException as se: print(f"串口异常: {str(se)}") except Exception as e: print(f"发送SMS失败: {str(e)}") def main(): ser = None try: # 打开串口 ser = serial.Serial(SERIAL_PORT, BAUD_RATE, timeout=TIMEOUT) time.sleep(2) # 等待调制解调器初始化 # 测试串口连通性 ser.write(b'AT\r') time.sleep(0.5) response = ser.read(ser.in_waiting).decode('utf-8') if "OK" not in response: print("调制解调器未响应,请检查串口配置") return # 读取手机号列表 phone_numbers = read_phone_numbers('phone_numbers.txt') message = '这是一条来自Python+GSM调制解调器的测试短信。' # 检查模拟余额 current_balance = check_simulated_balance() print(f"当前模拟余额: {current_balance:.2f} 元") # 遍历手机号发送短信(仅当余额足够时) for phone_number in phone_numbers: if check_simulated_balance() >= SMS_COST: send_sms(ser, phone_number, message) else: print(f"模拟余额不足,无法给 {phone_number} 发送短信") break # 余额不足时停止发送 except Exception as e: print(f"程序异常: {str(e)}") finally: # 关闭串口 if ser and ser.is_open: ser.close() print("串口已关闭") if __name__ == "__main__": main()
关键说明
- 模拟余额管理:通过
LOCAL_BALANCE变量模拟余额,发送短信后自动扣除SMS_COST设定的费用 - 串口优化:统一在
main函数中打开和关闭串口,避免原代码中每次调用函数都关闭串口导致的后续操作失败 - 余额判断逻辑:发送短信前检查模拟余额,余额不足时停止发送流程
- 响应处理:增加了对调制解调器响应的判断,确保短信发送成功后才扣除余额
内容的提问来源于stack exchange,提问作者Strong Imade
相关产品推荐
相关产品推荐

