公司动态
基于树莓派与Alexa的智能语音控制MM豆发射器项目全解析
1. 项目概述当MM遇上智能语音几年前当我第一次把树莓派和语音助手连在一起让台灯亮起来的时候那种“魔法成真”的感觉至今难忘。但说实话开关灯这种事玩几次也就腻了。直到有一天看着桌上那罐五颜六色的MM巧克力豆一个更“不务正业”的想法冒了出来能不能做个全自动的MM发射器然后动动嘴皮子就让Alexa把豆子精准地“投喂”到我手里这个想法听起来有点无厘头但背后串联起的硬件集成、云端服务对接和机械控制恰恰是智能家居和物联网创客项目的核心乐趣所在。这个“全自动MM发射器”项目本质上是一个由语音指令触发的微型物料分发系统。它的核心价值在于将一个看似简单的娱乐需求拆解成一套完整的、可复现的技术实现方案。你不再只是被动地使用智能音箱听歌、问天气而是让它成为你控制物理世界的入口。无论是想在工作间隙来点零食提神还是想在朋友面前秀一把“科技魔法”这个项目都能带来十足的成就感和趣味性。它适合所有对树莓派、Python编程、基础电路和智能家居联动感兴趣的爱好者无论你是想入门物联网还是寻找一个综合性的练手项目它都能让你在动手的过程中把分散的知识点串成一条线。2. 项目整体设计与核心思路拆解2.1 从想法到系统核心组件与工作流要实现“动口不动手”吃糖我们需要让一个完整的系统运转起来。整个工作流可以清晰地分为三个层次语音交互层、逻辑控制层和物理执行层。首先语音交互层的主角是亚马逊的Alexa。我们不会去破解或逆向她的核心而是利用亚马逊官方提供给开发者的“Alexa Skill Kit”工具创建一个自定义技能。这个技能就像一个专属的语音应用当你说出“Alexa让发射器给我一些MM豆”时这句话会被Alexa云端服务接收、识别并转化为一条结构化的指令消息发送给我们指定的后端服务。接下来是逻辑控制层这是项目的大脑由树莓派担任。树莓派上运行着一个用Python编写的服务程序。这个程序有两个关键任务第一它需要提供一个安全的、可通过互联网访问的端点来接收来自Alexa云端的指令第二它需要解析指令并决定如何驱动硬件。这里我们通常会使用像Flask-Ask这样的Python库来快速搭建一个能与Alexa Skill对话的Web服务大大简化了对接的复杂度。最后是物理执行层即真正的发射装置。树莓派通过其GPIO引脚连接和控制执行机构。考虑到MM豆子小巧、需要定量发射一个微型舵机配合定制的送料机构是性价比和可靠性最高的选择。舵机负责完成“推”或“拨”的动作将存储在料仓中的单颗豆子推出使其沿轨道滑落。整个硬件部分需要在一个稳定的结构上集成比如用亚克力板或3D打印件制作的外壳。注意方案选型的核心考量。为什么用舵机而不用步进电机或电磁铁舵机控制简单给定角度PWM信号即可扭矩适中价格低廉非常适合这种小行程、定点往复运动。步进电机控制复杂且通常用于需要连续旋转或精确定位的场景有点杀鸡用牛刀。电磁铁虽然反应快但难以实现柔和、可控的推出动作容易把豆子弹飞。因此舵机是这个场景下的“甜点”选择。2.2 技术栈选型与备选方案分析确定了核心思路我们来具体看看每个环节的技术选型及其替代方案这能帮助你在不同约束条件下做出调整。主控板树莓派 (Raspberry Pi)首选理由树莓派是创客项目的“瑞士军刀”。它不仅能通过GPIO控制硬件更关键的是它是一台完整的Linux电脑可以轻松运行Python Web服务处理来自云端的HTTPS请求。其社区支持庞大遇到问题几乎都能找到答案。备选方案ESP32/ESP8266如果你追求极致的成本和低功耗并且愿意将逻辑处理放到其他云端服务器如AWS IoT, BlynkESP系列是优秀的选择。但你需要额外搭建一个“中继”服务让Alexa Skill将指令转发给ESP设备增加了系统复杂性。Arduino 网络模块与ESP32情况类似Arduino本身联网和处理HTTP请求能力较弱需要搭配以太网盾或WiFi模块并依赖外部服务器进行桥接。语音交互Alexa Skill (Custom Skill)首选理由Alexa生态成熟开发工具链完善。通过创建自定义技能我们可以定义完全个性化的语音指令称为“话语”例如“给我豆子”、“发射糖果”、“来点彩色的”。Flask-Ask或ASK SDK等工具让后端开发变得非常直观。备选方案Google Assistant IFTTT通过IFTTT服务可以用更“无代码”的方式将语音指令触发一个Webhook从而调用你的树莓派服务。这种方式更简单但自定义化和灵活性不如直接开发Action。本地语音识别在树莓派上运行如Snowboy或Vosk的离线语音识别引擎完全脱离云端。优点是响应快、隐私好缺点是识别率、唤醒词训练和自然语言理解能力远不如成熟的云服务且无法使用“Alexa”这个便捷的唤醒方式。后端服务框架Python Flask Flask-Ask首选理由Flask是Python轻量级Web框架Flask-Ask是其专门用于对接Alexa Skill的扩展库。它抽象了Alexa复杂的请求/响应JSON格式让你可以用简单的Python函数和装饰器来处理意图入门极快。备选方案Node.js Alexa SDK如果你更熟悉JavaScript生态这是官方推荐的方案功能强大且文档齐全。直接解析HTTP请求对于学习底层原理有帮助但需要手动处理证书验证、请求签名校验和复杂的JSON解析不推荐用于生产或快速原型。执行机构微型舵机 (如SG90)首选理由如前所述SG90这类9克舵机价格便宜通常十几元驱动简单只需一根GPIO引脚输出PWM信号。其180度的转动范围足以设计出有效的推弹机构。备选方案连续旋转舵机如果你希望实现“持续出豆”而不是单发可以考虑。但控制精度不如标准舵机需要配合传感器来计数。螺线管电磁推杆动作迅猛适合需要瞬间爆发力的场景。但需要驱动电路如继电器或MOSFET管且控制的是“通断”而非“位置”难以实现柔和或可调节的推出力度。3. 核心细节解析与实操要点3.1 Alexa Skill 的创建与意图设计这是连接物理世界和语音世界的桥梁也是新手最容易感到困惑的地方。我们不是在树莓派上直接“编程”Alexa而是在亚马逊的开发者后台定义她的行为逻辑。首先你需要一个亚马逊开发者账号。登录后在Alexa Skills Kit中创建新技能。关键配置如下技能类型选择“自定义技能”。模型选择“自定义”这是最灵活的方式。调用名称这是你唤醒技能时说的名字比如“巧克力发射器”。之后你就可以说“Alexa打开巧克力发射器”或“Alexa告诉巧克力发射器发射豆子”。技能的核心是“交互模型”它由意图和话语构成。一个意图代表用户想要完成的一个动作。对于我们的发射器至少需要两个意图LaunchIntent当用户只说“打开巧克力发射器”时触发用于欢迎和提示。DispenseIntent当用户要求发射豆子时触发。这是最重要的意图。在DispenseIntent中你需要定义“话语样本”。这是训练Alexa理解用户多种说法的关键。例如“给我一些豆子”“发射”“来点MM”“投喂我一颗糖”Alexa会利用这些样本学习将类似的用户语句映射到同一个DispenseIntent。你还可以在意图中定义“槽位”用于捕获变量比如“给我{数量}颗豆子”其中{数量}就是一个槽位类型可以是数字。这为未来功能扩展如定量发射留出了空间。实操心得话语设计的技巧。尽量覆盖多种常见的口语表达方式包括中英文混合如果你的技能支持。但不要过度设计初期聚焦核心功能。一个常见的坑是话语样本之间差异过小可能导致识别冲突。确保每个样本都有足够的区分度。3.2 树莓派后端服务的搭建与安全对接树莓派上的Python服务是整个系统的中枢。它使用Flask-Ask来创建一个Web应用这个应用会暴露一个HTTPS端点。Alexa云端在识别你的语音指令后会将请求发送到这个端点。第一步基础环境搭建。在树莓派上安装Python3和pip然后创建虚拟环境并安装核心依赖sudo apt update sudo apt upgrade -y sudo apt install python3-pip python3-venv -y cd ~ mkdir mnm_launcher cd mnm_launcher python3 -m venv venv source venv/bin/activate pip install flask flask-ask第二步编写核心服务代码。创建一个app.py文件内容骨架如下from flask import Flask from flask_ask import Ask, statement, question, session import RPi.GPIO as GPIO import time app Flask(__name__) ask Ask(app, /alexa) # Alexa技能将请求发送到 /alexa 端点 # 初始化GPIO假设舵机接在GPIO 18引脚 SERVO_PIN 18 GPIO.setmode(GPIO.BCM) GPIO.setup(SERVO_PIN, GPIO.OUT) pwm GPIO.PWM(SERVO_PIN, 50) # 50Hz PWM频率适用于舵机 pwm.start(0) # 初始占空比为0舵机不动 def dispense_mnm(): 控制舵机完成一次发射动作 # 舵机角度控制占空比2.5%对应0度12.5%对应180度。我们需要一个往复动作。 # 假设中间位置是7.5%90度推出动作是12.5%然后返回。 pwm.ChangeDutyCycle(7.5) # 回到初始位置如果不在 time.sleep(0.5) pwm.ChangeDutyCycle(12.5) # 执行推出动作 time.sleep(0.3) # 保持推出状态一小段时间 pwm.ChangeDutyCycle(7.5) # 返回 time.sleep(0.5) pwm.ChangeDutyCycle(0) # 停止信号防止舵机抖动 return True ask.launch def launch(): welcome_msg 巧克力发射器已就绪您可以说给我来点豆子。 return question(welcome_msg) # question会保持会话开启 ask.intent(DispenseIntent) def dispense(): success dispense_mnm() if success: msg 豆子正在路上请接好 else: msg 哎呀发射好像出了点问题。 return statement(msg) # statement会结束本次会话 if __name__ __main__: # 注意在生产环境中应使用WSGI服务器如Gunicorn来运行并用Nginx反向代理。 # 且必须使用HTTPS下面这行仅用于本地测试。 app.run(host0.0.0.0, port5000, debugTrue)第三步也是最关键的一步内网穿透与HTTPS。Alexa云端服务只能回调一个公网可访问的HTTPS端点端口443。你的树莓派在家用路由器后面没有公网IP这就需要内网穿透工具。ngrok是最简单快速的选择。在ngrok官网注册获取你的Authtoken。在树莓派上下载并配置ngrok启动它将树莓派的5000端口暴露到公网./ngrok http 5000ngrok会生成一个随机的https://xxxxxx.ngrok.io域名。这个就是你的公网HTTPS端点。第四步技能端点配置。回到亚马逊开发者后台在技能配置的“端点”部分选择“HTTPS”并填入你的ngrok地址加上你在代码中定义的路径例如https://xxxxxx.ngrok.io/alexa。同时选择“我的开发端点具有由亚马逊信任的证书颁发机构颁发的SSL证书的子域”。ngrok的证书是受信的所以可以选这个。重要警告安全与稳定性。ngrok免费版地址每次重启都会变化且带宽有限仅适用于开发和演示。绝对不要用于任何正式或长期服务。对于长期项目你有两个可靠选择1) 向你的宽带运营商申请公网IP通常动态并在路由器上设置DDNS和端口转发然后为树莓派申请一个免费的SSL证书如Let‘s Encrypt。2) 将后端服务部署到稳定的云服务器如AWS EC2、Google Cloud Run树莓派仅作为硬件客户端通过WebSocket或MQTT从云端接收指令。方案2将硬件控制与网络服务解耦是更健壮的架构。3.3 机械结构与电路连接详解硬件部分是想法落地的实体。一个可靠的结构能极大减少调试的烦恼。机械结构设计核心是一个“单发供弹仓”。我设计了一个简单的方案用3D打印实现储料仓一个垂直的、底部有狭窄出口的管子可以容纳数十颗MM豆。出口宽度只允许一颗豆子通过。阻弹机构在出口处有一个由舵机臂控制的挡片。默认状态下挡片挡住出口豆子不会掉落。发射轨道挡片下方是一个倾斜的平滑轨道可以用塑料片弯折。工作原理当舵机收到信号转动时舵机臂拉动挡片缩回一颗豆子因重力落下掉在轨道上并滑出。舵机随即回位挡片伸出挡住下一颗豆子。这个过程完成一次单发。如果你没有3D打印机也可以用厚纸板、亚克力板和热熔胶手工制作。关键是保证储料仓出口和挡片的配合要精密防止一次掉出多颗豆子。电路连接树莓派和舵机的连接非常简单但需要注意功率问题。信号线橙色/白色连接至树莓派的GPIO 18或其他任意PWM capable的GPIO如12, 13。电源线红色切勿直接连接到树莓派的5V引脚树莓派的GPIO引脚供电能力有限约~50mA而舵机工作瞬间电流可能高达500-1000mA这会导致树莓派电压不稳甚至重启。正确的做法是使用一个外部5V电源如手机充电器搭配USB breakout板或专用的5V稳压模块为舵机供电。地线棕色/黑色同时连接到外部电源的GND和树莓派的GND任意一个即可。这一步至关重要它确保了树莓派和外部电源有共同的参考地电位。一个安全的连接示意图如下外部5V电源正极 --- 舵机 红线 外部5V电源负极 --- 舵机 黑线 树莓派 GND 引脚 树莓派 GPIO 18 --- 舵机 信号线橙/白4. 实操过程与核心环节实现4.1 环境配置与依赖安装全记录让我们从头开始在树莓派上搭建一个干净的工作环境。我假设你使用的是树莓派OS原Raspbian的最新版本。首先进行系统更新和基础工具安装sudo apt update sudo apt full-upgrade -y sudo apt install -y python3-pip python3-venv git为项目创建独立的虚拟环境是一个好习惯可以避免包版本冲突mkdir -p ~/projects/mnm_launcher cd ~/projects/mnm_launcher python3 -m venv .venv source .venv/bin/activate # 激活后命令行提示符前会出现 (.venv)安装Python依赖。除了Flask和Flask-Ask我们还需要RPi.GPIO来控制硬件pip install flask flask-ask RPi.GPIO如果你打算使用ngrok进行内网穿透测试去官网下载对应ARM架构的版本wget https://bin.equinox.io/c/bNyj1mQVY4c/ngrok-v3-stable-linux-arm.tgz tar -xzf ngrok-v3-stable-linux-arm.tgz sudo mv ngrok /usr/local/bin/ # 配置你的authtoken (从ngrok官网获取) ngrok config add-authtoken YOUR_AUTH_TOKEN4.2 服务端代码的逐行实现与优化基础的app.py代码前面已经给出这里我们进行优化和功能增强使其更健壮。优化一添加GPIO资源管理。原始代码中GPIO资源没有被正确释放多次运行后可能导致警告或错误。我们使用try...finally语句确保程序退出时清理GPIO。from flask import Flask from flask_ask import Ask, statement import RPi.GPIO as GPIO import time import atexit app Flask(__name__) ask Ask(app, /alexa) SERVO_PIN 18 pwm None def setup_gpio(): global pwm GPIO.setmode(GPIO.BCM) GPIO.setup(SERVO_PIN, GPIO.OUT) pwm GPIO.PWM(SERVO_PIN, 50) # 50Hz pwm.start(0) # 启动后先让舵机归位到安全角度 pwm.ChangeDutyCycle(7.5) time.sleep(0.5) pwm.ChangeDutyCycle(0) def cleanup_gpio(): if pwm: pwm.stop() GPIO.cleanup() print(GPIO cleaned up.) # 注册退出时的清理函数 atexit.register(cleanup_gpio) def dispense_mnm(): try: pwm.ChangeDutyCycle(12.5) # 推出 time.sleep(0.25) # 推出持续时间可调节 pwm.ChangeDutyCycle(7.5) # 收回 time.sleep(0.5) # 收回后稳定时间 pwm.ChangeDutyCycle(0) # 停止信号 return True except Exception as e: print(fDispense error: {e}) return False ask.launch def launch(): return statement(发射器准备好了。想尝尝巧克力豆吗) ask.intent(DispenseIntent) def dispense(): speech_text 正在发射请接好 if dispense_mnm(): return statement(speech_text) else: return statement(抱歉发射机构似乎卡住了。) if __name__ __main__: setup_gpio() try: # 生产环境请勿使用debugTrue并换用生产级服务器 app.run(host0.0.0.0, port5000, debugFalse, threadedTrue) except KeyboardInterrupt: pass finally: cleanup_gpio()优化二使用线程执行发射动作。在Web服务中如果dispense_mnm()函数执行时间稍长比如加了复杂动作可能会阻塞其他请求。我们可以用线程来异步执行这个任务让Alexa能立即回复用户。from threading import Thread # ... 其他导入和设置 ... def async_dispense(): 在后台线程中执行发射 time.sleep(0.1) # 稍作延迟确保响应已发送给Alexa dispense_mnm() ask.intent(DispenseIntent) def dispense(): # 立即启动一个线程去处理发射主线程立即返回响应 thread Thread(targetasync_dispense) thread.start() return statement(豆子马上就到)优化三添加简单的状态反馈。我们可以让技能在发射前和发射后给出不同的音效或更丰富的语音反馈这需要在返回的语句中嵌入SSML标记。ask.intent(DispenseIntent) def dispense(): thread Thread(targetasync_dispense) thread.start() speech speak正在准备发射 audio srcsoundbank://soundlibrary/weapons/amzn_sfx_blaster_01/ 嗖你的豆子出发了。/speak return statement(speech).simple_card(titleMM发射器, content已发射一颗MM豆)这里使用了Alexa内建的声音库来增加趣味性。.simple_card会在Alexa App中显示一个通知卡片。4.3 硬件组装、调试与校准硬件部分的成功八成靠设计两成靠调试。组装步骤结构固定首先将树莓派、面包板如果需要和舵机固定在你的底座如一块木板或亚克力板上。使用尼龙柱或螺丝确保牢固。连接电路按照前述的电路图接线。务必先断开所有电源。先连接地线再连接信号线最后连接电源线。使用杜邦线时确保插接牢固。安装机械部分将舵机臂安装到舵机上并将你制作的挡片机构与舵机臂牢固连接。手动转动舵机臂观察挡片是否能顺畅地阻挡和放开出豆口。调整挡片的角度和位置直到动作清晰有效。装载测试放入几颗MM豆手动触发舵机动作可以写一个简单的测试脚本观察豆子是否每次只掉落一颗以及滑行轨迹是否理想。你可能需要调整轨道的倾斜角度和出口形状。舵机校准舵机的“角度”是通过PWM信号的占空比控制的但不同品牌、甚至同品牌不同个体之间脉宽与角度的对应关系可能有微小差异。标准的50Hz PWM下占空比2.5%(脉冲宽度0.5ms) 通常对应0度。占空比7.5%(脉冲宽度1.5ms) 通常对应90度中立位。占空比12.5%(脉冲宽度2.5ms) 通常对应180度。你需要通过测试找到适合你机械结构的精确占空比。写一个简单的校准脚本import RPi.GPIO as GPIO import time SERVO_PIN 18 GPIO.setmode(GPIO.BCM) GPIO.setup(SERVO_PIN, GPIO.OUT) pwm GPIO.PWM(SERVO_PIN, 50) pwm.start(0) try: while True: angle float(input(Enter duty cycle (e.g., 7.5 for neutral): )) pwm.ChangeDutyCycle(angle) print(fSet to {angle}%) except KeyboardInterrupt: pass finally: pwm.stop() GPIO.cleanup()运行这个脚本输入不同的占空比值如2.5, 7.5, 12.5观察舵机臂的实际位置并记录下“完全阻挡”和“完全放开”两个位置对应的占空比将其更新到主程序的dispense_mnm函数中。5. 常见问题与排查技巧实录在搭建和运行这个项目的过程中你几乎一定会遇到下面这些问题。我把它们和解决方案整理出来希望能帮你节省大量时间。5.1 Alexa技能端对接失败这是最常出现的问题症状是你在Alexa开发者后台测试时技能返回“服务端错误”或“无法访问技能”。问题1ngrok隧道断开或地址变化。排查在树莓派上运行curl https://localhost:5000/alexa或你的本地端点确保本地服务正常。然后检查ngrok的Web界面运行ngrok后通常会给出一个本地管理地址如http://127.0.0.1:4040查看隧道状态和最近的请求日志。解决重启ngrok获得新地址并立即更新到Alexa技能配置的端点URL中。确保技能模型已保存并重新构建。问题2SSL证书问题。排查Alexa对HTTPS证书要求严格。确保你的端点URL是https://开头且证书有效。对于ngrok这通常不是问题。但如果你使用自签名证书或某些DDNS服务提供的免费证书可能会被Alexa拒绝。解决坚持使用ngrok进行测试或换用受信任的证书如Let‘s Encrypt。在技能端点配置中根据你的证书类型正确选择“我的开发端点具有由亚马逊信任的证书颁发机构颁发的SSL证书的子域”或另一个选项。问题3技能交互模型未构建或未匹配。排查在开发者控制台的“测试”标签页尝试输入你定义的“话语样本”查看它是否被正确识别为DispenseIntent。如果没有说明交互模型可能未保存或话语设计不够全面。解决在“构建”标签页确保点击了“保存模型”然后“构建模型”。构建成功后在“测试”标签页将技能测试从“禁用”改为“开发”模式。问题4后端服务代码错误或未运行。排查查看树莓派上运行app.py的终端是否有Python错误信息。同时检查防火墙是否屏蔽了5000端口sudo ufw status。解决根据错误信息修正代码。确保服务绑定到0.0.0.0而非127.0.0.1。临时关闭防火墙测试sudo ufw disable测试后记得重新开启并放行5000端口sudo ufw allow 5000。5.2 舵机不动作或动作异常问题1舵机完全不动但有嗡嗡声。排查这是典型的供电不足现象。树莓派的5V引脚无法提供舵机启动所需的大电流。解决立即改用外部5V电源为舵机供电。确保电源有足够的电流输出能力至少1A。同时务必将外部电源的地线与树莓派的地线连接。问题2舵机乱转或角度不准。排查PWM信号不稳定或占空比计算错误。首先检查接线是否松动尤其是信号线。然后用校准脚本测试确认占空比与角度的对应关系。解决确保PWM频率设置为50Hz。通过校准找到精确的占空比值。在代码中每次改变占空比后尤其是最后设置为0停止后可以添加一个极短的time.sleep(0.05)让信号稳定。问题3舵机发热严重。排查舵机在到达目标位置后如果持续收到PWM信号会持续用力“顶住”导致发热。我们的代码中在动作结束后设置了占空比为0就是为了让舵机放松。如果没设置就会发热。解决确保在每个动作周期结束后都执行pwm.ChangeDutyCycle(0)。或者更优雅的方式是在初始化时设置好角度后就调用pwm.stop()只在需要动作时再pwm.start(0)并改变占空比动作完再stop()。5.3 机械结构卡豆或连发问题1一次掉出多颗豆子。排查出豆口太宽或者挡片收回时上方的豆子因堆积压力一起挤了出来。解决收窄出豆口确保其宽度只比一颗MM豆的直径略大。在储料仓设计上可以采用“之”字形或漏斗形通道减少豆子对出口的直接压力。也可以在挡片上方增加一个柔软的毛刷或弹簧提供轻微阻力。问题2豆子卡在出口或轨道上。排查轨道不够光滑倾斜角度不够或者有毛刺。解决用砂纸打磨轨道内表面确保光滑。增大轨道倾斜角度。在关键转折点使用热熔胶做出圆滑过渡。对于MM豆这种有糖衣的潮湿天气可能轻微粘连保持环境干燥或在轨道上涂抹极少量的食品级润滑剂如石墨粉需谨慎。5.4 服务运行与稳定性问题问题1树莓派重启后服务不自动启动。解决使用systemd创建后台服务。创建一个服务文件sudo nano /etc/systemd/system/mnm-launcher.service[Unit] DescriptionMM Launcher Alexa Service Afternetwork.target [Service] Typesimple Userpi WorkingDirectory/home/pi/projects/mnm_launcher EnvironmentPATH/home/pi/projects/mnm_launcher/.venv/bin ExecStart/home/pi/projects/mnm_launcher/.venv/bin/python /home/pi/projects/mnm_launcher/app.py Restarton-failure RestartSec10 [Install] WantedBymulti-user.target然后启用并启动它sudo systemctl enable mnm-launcher.service和sudo systemctl start mnm-launcher.service。问题2ngrok免费版连接不稳定经常断线。解决如前所述ngrok仅用于测试。长期方案是使用DDNS端口转发SSL证书或者将后端服务部署到云服务器。对于云方案你可以将Flask应用部署到Heroku、PythonAnywhere或AWS Lambda配合API Gateway树莓派则作为一个客户端通过WebSocket或定期轮询从云端获取指令。这彻底解决了公网IP和HTTPS的问题也使得你可以从任何地方管理设备。