基于MicroPython与LINE Notify的物联网设备通知系统开发实践
1. 项目概述:让MCU开口说话
在物联网项目里,让设备“开口说话”,主动把状态、数据或者告警信息推送到你的手机上,是一个既实用又酷炫的功能。想象一下,家里的温湿度传感器检测到异常高温,能立刻给你发条消息;或者你DIY的智能鱼缸,在水质变差时能及时通知你。这种主动通知的能力,是区分一个“玩具”和一个“实用工具”的关键。
过去,要实现这个功能,你可能需要折腾复杂的MQTT服务器、自己搭建Webhook,或者研究各种云平台繁琐的API。对于资源有限的微控制器(MCU)来说,这无疑增加了开发和维护的复杂度。而LINE Notify这个服务,恰好提供了一个极其简单的解决方案:它本质上就是一个通过HTTP POST请求就能发送消息到LINE聊天室的通道。对于嵌入式开发者,尤其是使用MicroPython的玩家,这简直是天作之合。
MicroPython让我们能在ESP8266、ESP32这类MCU上用Python语法轻松编程,而围绕它生态出现的一些优秀库,则进一步把复杂度封装了起来。就像这个项目里用到的 My_NetHTTP_LINE 库,它的目标非常明确——把“通过WiFi联网,构造HTTP请求,向LINE Notify发送消息”这一系列操作,浓缩成两、三行直观的代码。你不再需要关心HTTP头的构造、URL编码或者连接管理,只需要关注最核心的两件事:你的WiFi密码和LINE令牌(Token)。接下来,我们就从最基础的准备开始,一步步拆解如何让你的MCU变身成一个智能通知器。
2. 前期准备与环境搭建
在写下第一行代码之前,我们需要把“舞台”搭好。这包括硬件设备、软件工具以及关键的云端服务配置。别担心,每一步我都会解释清楚为什么这么做,以及有哪些容易踩坑的地方。
2.1 硬件与软件准备
硬件选择:ESP8266 vs ESP32 核心硬件是一块支持WiFi和MicroPython的MCU开发板。最常见的选择是ESP8266(如NodeMCU、Wemos D1 mini)和ESP32系列。
- ESP8266 :性价比之王,单核,足以胜任网络连接和简单的消息发送任务。如果你的项目只需要联网发通知,没有其他复杂计算或外设需求,ESP8266完全够用,而且更便宜。
- ESP32 :功能更强大,双核处理器,主频更高,内存更大,还多了蓝牙功能。如果你的项目未来需要连接更多传感器、处理更复杂的数据,或者需要用到蓝牙,ESP32是更面向未来的选择。
注意 :无论选择哪款,务必确保板子有可靠的USB转串口芯片(如CP2102、CH340),并且驱动已在你的电脑上安装好。连接不稳定是后续一切问题的万恶之源。
软件工具链
- MicroPython固件 :你需要将MicroPython解释器“刷入”你的MCU。去MicroPython官网下载对应你板型(如
esp8266-xxx.bin或esp32-xxx.bin)的最新稳定版固件。 - 烧录工具 :对于ESP系列,
esptool.py是官方的命令行烧录工具,功能强大。如果你更喜欢图形界面,像ThonnyIDE内置的烧录功能或者Flash Download Tools(乐鑫官方)也不错。 - 开发环境(IDE) :强烈推荐 Thonny 。它对MicroPython的支持是“开箱即用”级的。连接板子后,它不仅能直接作为Python编辑器,还能充当一个简单的文件管理器,上传下载文件到MCU的内部文件系统,以及使用其自带的REPL(交互式命令行)进行调试,这对我们后续上传库文件至关重要。
- 库文件 :本项目依赖的核心库文件(
My_NetHTTP.py,My_NetHTTP_LINE.py, 以及可选的My_Wifi.py)。你需要提前获取这些.py文件。
2.2 获取LINE Notify令牌(Token)
这是连接你的代码和LINE账户的“钥匙”。没有它,消息不知道该发给谁。
- 访问 LINE Notify 官网 (请自行搜索正确网址),使用你的LINE账户登录。
- 点击页面右上角你的头像,进入“个人页面”。
- 找到“发行存取令牌”(Issue access token)选项。
- 输入一个令牌名称,例如“我的ESP32通知器”。这主要用于你自己识别这个令牌的用途。
- 选择消息要发送到的目标。你可以选择“透过1对1聊天接收LINE Notify的通知”,这样消息会单独发给一个名为“LINE Notify”的好友;也可以选择一个你所在的群组,这样所有群成员都能看到设备消息。 出于隐私考虑,建议先使用1对1聊天进行测试。
- 点击“发行”。页面上会 一次性 显示一串长字符,这就是你的
LINE_NOTIFY_TOKEN。 务必立即复制并妥善保存 ,因为页面刷新后将无法再次查看,只能重新生成。
实操心得 :令牌是最高权限凭证,泄露意味着别人可以用你的令牌任意发消息。因此:
- 绝对不要 将令牌硬编码在提交到公开仓库的代码中。
- 在MicroPython中,一个常见的做法是将令牌(以及WiFi密码)保存在一个单独的、名为
secrets.py或config.py的文件里,然后在主程序中导入。上传时只上传主程序,将包含敏感信息的文件通过Thonny等工具单独上传,并确保.gitignore文件忽略了它。- 令牌可以在LINE Notify个人页面随时作废(失效)和重新生成。
2.3 库文件的上传与管理
原始资料提到了上传库文件到MCU,这里详细展开。MCU运行MicroPython时,需要一个文件系统来存放你的主程序 main.py 和依赖的库文件。我们通过串口连接,用工具将这些文件上传到MCU的闪存中。
使用Thonny上传(推荐给初学者):
- 将MCU通过USB线连接电脑,在Thonny中选择正确的端口和解释器(MicroPython ESP32/ESP8266)。
- 在Thonny下方窗格,通常可以看到“设备”和“本机”两个文件浏览器。
- 在“本机”侧找到你下载好的
My_NetHTTP.py,My_NetHTTP_LINE.py等文件。 - 右键点击文件,选择“上传到 /”,或者直接拖拽到“设备”侧的根目录下。
- 上传成功后,你可以在MCU的文件系统中看到它们。
使用命令行工具(如 ampy ): 如果你习惯命令行,可以安装 adafruit-ampy 工具。
# 上传单个文件
ampy --port COM3 put My_NetHTTP_LINE.py
# 上传整个目录(谨慎使用)
# ampy --port COM3 put lib/
注意事项 :
- 文件命名一致性 :确保你上传的文件名和代码中
import语句里的名字完全一致,包括大小写。MicroPython的文件系统有时对大小写敏感。- 存储空间 :ESP8266的可用文件系统空间可能较小(通常1MB左右),注意不要上传无关的大文件。ESP32则宽裕很多。
- 库的依赖 :
My_NetHTTP_LINE.py依赖于My_NetHTTP.py(处理基础的HTTP请求)。因此两个文件必须同时存在。My_Wifi.py是可选的,如果你用自己的WiFi连接代码,可以不用它。
3. 核心库原理与代码深度解析
现在,硬件就绪,令牌在手,库文件也已上传。让我们深入看看,那神奇的2~3行代码背后,到底发生了什么。理解原理,不仅能帮你更好地使用它,还能在出问题时快速定位。
3.1 My_NetHTTP_LINE 库的工作机制
My_NetHTTP_LINE 库是一个高级封装,它的目标是极致简化。我们看看它可能的核心实现逻辑(以下为概念性代码,并非原库 exact 代码):
# My_NetHTTP_LINE.py 概念性源码分析
import My_NetHTTP # 导入底层HTTP库
class myNotify:
def __init__(self, token):
# 保存令牌,并构造LINE Notify API的固定URL
self.url = "https://notify-api.line.me/api/notify"
self.headers = {
"Authorization": "Bearer " + token, # LINE API要求的认证头格式
"Content-Type": "application/x-www-form-urlencoded"
}
# 实例化一个底层的HTTP客户端
self.http = My_NetHTTP.My_NetHTTP() # 假设My_NetHTTP类名为My_NetHTTP
def send(self, message, package=None, sticker=None):
# 构建请求体,最基本的参数是 'message'
data = "message=" + self._urlencode(message)
# 如果提供了贴图参数,则添加到请求体中
if package is not None and sticker is not None:
data += "&stickerPackageId=" + str(package) + "&stickerId=" + str(sticker)
# 调用底层HTTP库的POST方法
# 这里封装了实际的网络请求、错误处理等复杂细节
response = self.http.post(self.url, data=data, headers=self.headers)
# 可能还会检查response状态码(如200成功,401令牌错误等)
return response
从这段概念代码可以看出,这个库主要做了以下几件事:
- 初始化 :接收你的令牌,并组合成LINE API要求的
Authorization: Bearer {token}请求头格式。这是HTTP协议中一种标准的令牌认证方式。 - 消息构造 :将你要发送的文本消息进行URL编码(处理空格、中文等特殊字符),形成
message=你的内容的标准表单数据格式。 - 贴图支持 :如果调用时传入了
package和sticker参数,它会将这两个参数拼接到请求体中。 - 发起请求 :最终,它调用更底层的
My_NetHTTP库,向https://notify-api.line.me/api/notify这个固定的API地址,发送一个HTTP POST请求。
那么,底层的 My_NetHTTP 库又做了什么? 它很可能封装了MicroPython标准库 urequests 或 socket 的复杂操作,包括:
- 建立TCP连接。
- 按照HTTP协议格式,组装完整的HTTP请求报文(请求行、请求头、空行、请求体)。
- 处理网络读写超时。
- 接收服务器的响应并解析状态码和响应体。
- 处理网络连接异常。
正是这种分层设计,才让顶层的我们能够用 line.send(“Hello”) 这样简单的方式完成通信。
3.2 代码逐行解读与最佳实践
让我们结合一个更完整的示例,逐行分析并融入最佳实践。
# 示例:complete_notify.py
from My_Wifi import myWifi # 导入WiFi连接库
from My_NetHTTP_LINE import myNotify # 导入LINE通知库
import time
# 1. WiFi连接配置
WIFI_SSID = "你的WiFi名称"
WIFI_PASSWORD = "你的WiFi密码"
LINE_TOKEN = "你的LINE令牌" # 强烈建议从配置文件导入
# 2. 创建WiFi对象并连接
wifi = myWifi()
print("正在连接WiFi...")
if wifi.connect(WIFI_SSID, WIFI_PASSWORD):
print("WiFi连接成功!")
# 3. 创建LINE通知对象
line = myNotify(LINE_TOKEN) # 初始化,传入令牌
# 4. 发送纯文本消息
print("正在发送文本消息...")
response = line.send("【设备启动通知】ESP32已成功上线,IP地址:" + wifi.get_ip())
# 这里可以检查response,例如 if response.status_code == 200: ...
# 5. 发送带贴图的消息
# packageId 和 stickerId 需要从LINE官网查询
print("正在发送带贴图的消息...")
line.send("今日天气晴好,一切正常!😊", package=1, sticker=113)
# 贴图ID 1-113 对应的是“微笑”表情
# 6. 模拟设备运行后发送告警
time.sleep(5) # 模拟运行5秒
# 假设这里读取传感器,发现温度过高
simulated_temperature = 38.5
if simulated_temperature > 35:
line.send(f"【高温告警】检测到温度过高:{simulated_temperature}°C!请及时处理。", package=2, sticker=165)
# 贴图ID 2-165 对应的是“吃惊”或“警告”类表情,更符合告警场景
# 7. 断开WiFi(可选,对于常开设备通常保持连接)
wifi.disconnect(3) # 参数3可能代表延迟3秒断开
print("通知发送完毕,WiFi已断开。")
else:
print("WiFi连接失败,请检查配置。")
关键点解析与最佳实践:
- WiFi连接判断 :
if wifi.connect(...):这是一个好习惯。确保网络连通后再进行后续的网络操作,避免程序因网络问题而崩溃。 - 令牌管理 :在实际项目中,
LINE_TOKEN、WIFI_SSID和WIFI_PASSWORD不应直接写在主代码里。创建一个config.py文件:
在主程序中# config.py WIFI_SSID = "my_home_wifi" WIFI_PASSWORD = "super_secret_password" LINE_TOKEN = "abcdefghijklmnopqrstuvwxyz123456"import config,然后使用config.LINE_TOKEN。上传代码时,只上传主程序,config.py通过Thonny单独上传。 - 消息内容 :消息内容可以动态拼接。如上例中,将获取到的设备IP地址加入通知,使得消息更具信息量。使用f-string(Python 3.6+)或
format()方法让字符串组合更清晰。 - 错误处理 :示例中省略了详细的错误处理。在生产代码中,你应该用
try...except包裹send方法,捕获可能发生的网络异常、内存错误等,并记录日志或通过其他途径告警。 - 贴图的情感化应用 :选择与消息内容情绪相符的贴图,能极大提升通知的友好度和可读性。告警用“紧张”、“吃惊”的贴图,正常报告用“微笑”、“OK”的贴图。
4. 实战进阶:构建一个温湿度监控通知器
理解了基础,我们来做一个更有实际意义的项目:一个基于DHT11/DHT22温湿度传感器和ESP32的监控器,它定期读取环境数据,并在温度或湿度超过阈值时,向LINE发送告警通知。
4.1 硬件连接与依赖库
所需材料:
- ESP32开发板 x1
- DHT11或DHT22温湿度传感器 x1
- 杜邦线若干
- 微型USB数据线
接线方式(以DHT11为例):
- DHT11 VCC 引脚 -> ESP32 3.3V
- DHT11 GND 引脚 -> ESP32 GND
- DHT11 DATA 引脚 -> ESP32 GPIO 4 (可根据需要更改)
额外的MicroPython库: 除了之前的网络库,我们还需要 dht 库来读取传感器数据。好消息是, dht 通常是MicroPython固件内置的标准库之一,无需额外上传。如果没有,你需要找到 dht.py 文件并上传。
4.2 完整项目代码实现
# main.py - 温湿度监控与LINE告警系统
import time
import dht
from machine import Pin
from My_Wifi import myWifi
from My_NetHTTP_LINE import myNotify
# 1. 配置文件(实际使用时请分离到config.py)
CONFIG = {
'wifi_ssid': '你的WiFi',
'wifi_pass': '你的密码',
'line_token': '你的令牌',
'sensor_pin': 4, # DHT数据线连接的GPIO引脚
'check_interval': 30, # 检查间隔(秒)
'temp_threshold_high': 28.0, # 温度告警上限(摄氏度)
'temp_threshold_low': 10.0, # 温度告警下限
'humi_threshold_high': 80.0, # 湿度告警上限(百分比)
'humi_threshold_low': 20.0 # 湿度告警下限
}
# 2. 初始化硬件与网络
def init_system():
# 初始化DHT传感器
dht_sensor = dht.DHT11(Pin(CONFIG['sensor_pin'])) # 使用DHT11,如果是DHT22改为DHT22
# 初始化WiFi
wifi = myWifi()
print("系统初始化...")
if not wifi.connect(CONFIG['wifi_ssid'], CONFIG['wifi_pass']):
print("[严重错误] WiFi连接失败,系统停止。")
# 对于无法联网的设备,可以考虑让LED闪烁报警
while True:
time.sleep(1) # 阻塞,等待人工干预或重启
print(f"WiFi连接成功,IP: {wifi.get_ip()}")
# 初始化LINE通知器
line_bot = myNotify(CONFIG['line_token'])
# 发送系统启动通知
line_bot.send(f"🌡️ 温湿度监控器已启动 @ {wifi.get_ip()}, 开始监控...")
return dht_sensor, wifi, line_bot
# 3. 读取传感器数据(包含简单错误处理)
def read_sensor_data(sensor):
try:
sensor.measure() # 触发一次测量
temperature = sensor.temperature()
humidity = sensor.humidity()
# DHT11可能返回None或错误值,增加检查
if temperature is None or humidity is None:
print("读取传感器数据失败,返回None。")
return None, None
# 有时DHT11会读出极端错误值,增加合理性检查
if -40 < temperature < 80 and 0 <= humidity <= 100:
return temperature, humidity
else:
print(f"传感器数据异常:temp={temperature}, humi={humidity}")
return None, None
except OSError as e:
# 常见的传感器读取超时错误
print(f"读取传感器时发生OSError: {e}")
return None, None
except Exception as e:
print(f"读取传感器时发生未知错误: {e}")
return None, None
# 4. 检查阈值并发送通知
def check_and_notify(temp, humi, line_bot, last_alert):
current_time = time.time()
message_parts = [] # 用于组合消息
alert_level = 0 # 告警级别 0:正常,1:警告,2:严重
# 检查温度
if temp is not None:
if temp > CONFIG['temp_threshold_high']:
message_parts.append(f"🔥 温度过高:{temp}°C")
alert_level = max(alert_level, 2)
elif temp < CONFIG['temp_threshold_low']:
message_parts.append(f"❄️ 温度过低:{temp}°C")
alert_level = max(alert_level, 2)
else:
message_parts.append("温度传感器读数无效")
alert_level = max(alert_level, 1)
# 检查湿度
if humi is not None:
if humi > CONFIG['humi_threshold_high']:
message_parts.append(f"💦 湿度过高:{humi}%")
alert_level = max(alert_level, 2)
elif humi < CONFIG['humi_threshold_low']:
message_parts.append(f"🏜️ 湿度过低:{humi}%")
alert_level = max(alert_level, 2)
else:
message_parts.append("湿度传感器读数无效")
alert_level = max(alert_level, 1)
# 决定是否发送通知以及发送什么
if alert_level > 0:
# 存在告警
alert_msg = " | ".join(message_parts)
# 防骚扰机制:相同的告警,至少间隔10分钟才发送一次
if alert_msg != last_alert.get('msg') or (current_time - last_alert.get('time', 0)) > 600:
print(f"发送告警:{alert_msg}")
if alert_level == 2:
line_bot.send(alert_msg, package=2, sticker=165) # 严重告警用紧张贴图
else:
line_bot.send(alert_msg, package=1, sticker=113) # 一般警告用提醒贴图
last_alert['msg'] = alert_msg
last_alert['time'] = current_time
else:
# 状态正常,可以定期发送一次心跳(例如每小时一次),这里省略以节省消息数
# if current_time - last_heartbeat > 3600: ...
# line_bot.send(f"✅ 状态正常 - 温度:{temp}°C, 湿度:{humi}%")
pass
return last_alert
# 5. 主循环
def main():
sensor, wifi, line_bot = init_system()
last_alert = {'msg': '', 'time': 0} # 记录上一次告警内容和时间
normal_read_count = 0
while True:
print(f"\n--- 第{normal_read_count+1}次检查 ---")
temp, humi = read_sensor_data(sensor)
if temp is not None and humi is not None:
print(f"当前环境:温度 {temp}°C, 湿度 {humi}%")
# 更新最后一次告警状态
last_alert = check_and_notify(temp, humi, line_bot, last_alert)
normal_read_count += 1
else:
print("本次传感器读取失败,跳过检查。")
# 连续多次失败可以升级为告警
# error_count += 1
# if error_count > 5: ...
# 等待下一个检查周期
time.sleep(CONFIG['check_interval'])
# 运行主程序
if __name__ == '__main__':
main()
4.3 项目优化与扩展思路
这个基础版本已经可以工作,但还有很大的优化和扩展空间:
-
深度睡眠与省电 :如果设备由电池供电,频繁的WiFi连接和传感器读取非常耗电。可以利用ESP32的深度睡眠(Deep Sleep)功能。让设备每隔一段时间(如5分钟)唤醒,连接WiFi、读取传感器、发送通知(如果需要),然后立刻进入深度睡眠。这可以将平均电流从几十mA降至几十μA,极大延长续航。
from machine import deepsleep # 在主循环末尾或发送通知后 print("进入深度睡眠,{}秒后唤醒。".format(sleep_time_ms // 1000)) deepsleep(sleep_time_ms) # 单位是毫秒 -
数据上报与可视化 :除了即时告警,你还可以将数据定期上报到物联网平台(如ThingsBoard、Blynk、或者自建的InfluxDB+ Grafana),用于绘制长期的历史曲线图,分析环境变化趋势。这需要设备具备更稳定的网络连接和更复杂的数据封装能力。
-
多通道通知 :不要只依赖LINE。可以集成其他通知方式,比如Telegram Bot、Bark(iOS)、Server酱(微信)等。在
check_and_notify函数中,可以同时调用多个通知发送函数,实现通知冗余,确保重要告警不被遗漏。 -
本地显示与交互 :增加一个OLED屏幕(如SSD1306),实时显示当前的温湿度数据和WiFi状态。再增加一两个按钮,可以手动触发一次读取、切换显示模式,或者进入配置模式(通过Web Server或蓝牙)来修改WiFi密码和阈值,这样就不需要每次都修改代码并重新上传了。
5. 常见问题排查与调试技巧
即使按照步骤操作,你也可能会遇到一些问题。这里汇总了一些常见坑点及其解决方法。
5.1 网络连接类问题
| 问题现象 | 可能原因 | 排查步骤与解决方案 |
|---|---|---|
wifi.connect() 始终返回 False 或超时。 |
1. WiFi SSID/密码错误。 2. 路由器设置了MAC地址过滤或隐藏了SSID。 3. ESP板与路由器距离过远或信号太差。 4. 路由器不支持ESP的某些WiFi模式(较少见)。 |
1. 仔细核对 SSID和密码,注意大小写和特殊字符。 2. 在路由器后台暂时关闭MAC过滤,或将ESP的MAC地址加入白名单。对于隐藏SSID, myWifi 库可能不支持,需查看其文档或改用标准 network 库手动连接。 3. 将设备靠近路由器测试。 4. 尝试在手机热点下测试,以排除路由器兼容性问题。 |
| 连接WiFi成功,但发送LINE消息时失败。 | 1. 网络临时波动。 2. DNS解析失败(无法解析 notify-api.line.me )。 3. 防火墙或网络策略阻止了对外部HTTPS(443端口)的访问。 |
1. 增加重试机制。在 send 方法外用 try...except 包裹,失败后延迟几秒重试1-2次。 2. 尝试在代码中先用 urequests.get('http://example.com') 测试是否能访问普通HTTP网站,以排除基础网络问题。 3. 在某些企业或学校网络,访问外部服务可能受限。尝试切换到手机热点网络测试。 |
| 设备运行一段时间后网络断开,无法重连。 | 1. WiFi路由器重启或网络不稳定。 2. ESP32/ESP8266的WiFi驱动或电源管理存在bug,导致长时间运行后断线。 3. 代码中没有断线重连机制。 |
1. 在主循环中增加网络状态检查。可以定期(如每10次循环)ping一个网关或外网地址,如果失败,则调用 wifi.disconnect() 然后重新执行 wifi.connect() 。 2. 查阅MicroPython论坛,有时更新到最新稳定版固件可以解决一些已知的驱动问题。 3. 务必实现重连逻辑 ,这是物联网设备稳定性的关键。 |
5.2 代码与库相关错误
| 问题现象 | 可能原因 | 排查步骤与解决方案 |
|---|---|---|
ImportError: no module named 'My_NetHTTP_LINE' |
1. 库文件没有上传到MCU。 2. 库文件上传到了错误的目录(如子目录)。 3. 文件名拼写错误(大小写、下划线)。 |
1. 使用Thonny的文件管理器,确认 My_NetHTTP_LINE.py 和 My_NetHTTP.py 存在于MCU的根目录( / )。 2. 确保 import 语句中的模块名与文件名 完全一致 。 |
NameError: name 'myNotify' is not defined |
from My_NetHTTP_LINE import myNotify 语句执行失败,但错误被忽略或发生在之前。 |
检查上一条 import 语句是否成功。确保库文件存在且语法正确。可以在REPL中单独执行 from My_NetHTTP_LINE import myNotify 测试。 |
| 发送消息后程序崩溃或无响应。 | 1. 内存不足(尤其在ESP8266上,同时处理字符串和网络请求易发生)。 2. 网络操作阻塞了看门狗(WDT),导致复位。 |
1. 使用 gc.collect() 在关键操作(如组包大字符串、发送请求)后手动回收内存。 2. 将耗时的网络操作放在 try...finally 块中,或在其中插入短时间的 time.sleep(0) 以喂狗。对于ESP32,可以考虑将网络任务放在另一个核心上运行(需使用 _thread 库)。 |
| 能发送文本,但发送贴图失败。 | 1. packageId 或 stickerId 参数类型错误(应为整数)。 2. 参数值超出了有效范围。 3. 库的 send 方法在处理可选参数时存在bug。 |
1. 确认传入的参数是整数,如 line.send("msg", package=1, sticker=113) 。 2. 去LINE官方贴图列表页面,确认你使用的ID组合是有效的、免费的贴图。 3. 尝试发送不带贴图的消息确认基础功能正常。然后检查库文件源码(如果开源),看贴图参数拼接逻辑是否正确。 |
5.3 LINE API 返回错误
当 send 方法内部调用失败时,最可能的原因是LINE API返回了错误。虽然 My_NetHTTP_LINE 库可能没有直接暴露详细的错误信息,但我们可以通过修改库文件或使用更底层的 urequests 库来调试。
临时调试方法:
- 在
My_NetHTTP_LINE.py的send方法中,找到发送请求和获取响应的代码行(通常是response = self.http.post(...))。 - 在这行之后,添加打印语句,输出响应的状态码和内容。
# 在My_NetHTTP_LINE.py的send方法内添加 print("Status Code:", response.status_code) print("Response:", response.text) - 重新上传该库文件到MCU并运行你的程序。常见的错误有:
- 401 :令牌无效或已过期。请重新在LINE Notify官网生成令牌。
- 400 :请求格式错误,例如消息体过长(LINE Notify限制消息长度)、贴图ID无效等。
- 429 :请求频率过高。LINE Notify对同一个令牌有发送频率限制(大概每小时1000条左右),请降低发送频率。
调试心法:
- 分而治之 :遇到问题,先把复杂系统拆开测试。先写一个最简单的脚本,只连WiFi;再写一个脚本,只发LINE文本;最后再组合。
- 利用REPL :Thonny的REPL是强大的实时调试工具。你可以在里面逐行执行代码,即时查看变量和错误信息。
- 打印日志 :在关键步骤(连接WiFi前/后、发送消息前/后)添加
print()语句输出状态,这是嵌入式调试最朴实但最有效的方法。
更多推荐

所有评论(0)