如何将极米new Z6X接入米家,实现小爱控制蓝牙开机及Wifi关机等功能是一个不小的挑战。本文将为你提供详细的教程,帮助你轻松实现极米new Z6X与米家的完美结合。
参考前人的经验,使用ESP32开发板,写了个程序,实现了极米new Z6X投影仪接入米家,小爱控制的功能。
主要实现的有:
1、Wifi接入巴法,实现米家控制;
2、蓝牙广播特定manufacturer data实现完美蓝牙开机;
3、Wifi UDP广播实现复杂指令的完美快速关机。
======================分割线=====================
2024.1.7更新
先说一下思路:先研究极米蓝牙遥控器开机时发射的蓝牙广播特点,再测试wifi udp广播的指令关机,没问题后使用ESP32的蓝牙和wifi模块分别模拟遥控器和手机app的关机指令。最后把这个开关功能接入巴法实现完美小爱同学开关机
一、先说开机,这个方案是用ESP32发送一个蓝牙广播,模拟原机遥控器实现的开机功能,所以不用考虑接智能开关的方案了。 使用的ESP32如图:
极米的蓝牙遥控测试:
1. 需要一个苹果的ios设备,在App Store下载 bluetooth smart scanner app,安卓上好像nRF Connect也可以实现类似功能,github上能下载到。
2. 将你的 投影仪主机彻底断开电源。
3. 不停的按遥控器上的开机按键,这时在bluetooth smart scanner app上应该可以找到遥控器发射的ble advertisement信号,我的会出现名称为Bluetooth 4.0 RC的设备
4. 在上面的信号中,找到manufactorer data,我的遥控器在按下开关键时会快速闪动显示如图的字符<46004617 03efb224 40ffffff 3043524b 544d> 这个manufactorer data是模拟蓝牙遥控的关键。有的设备可以在网上查到,ios - How can I clone a non-paired BLE signal from a remote to trigger a device? - Stack Overflow ,但最好还是自己测一下。
5. 建议先通过EFR connect. 这个安卓app, 验证下能否使用上面的manufactorer data唤起投影仪。
如果能成功使用上面图中的Manufacturer data填写方法成功打开投影仪,这步就成功了。
======================分割线=====================
二、Wifi关机功能
这部分我是直接沿用前面几位大佬的研究直接拿来用,总结一下:
极米有2套api可用,一套是复杂指令,一套是简单的按键输入,所有指令均是通过upd连接到目标机器上。
复杂api
端口:16750
指令内容如以下格式:
- {"action":20000,"controlCmd":{"delayTime":0,"mode":6,"time":0,"type":0},"msgid":"2"}
复制代码
可以实现快速关机,不用等15秒。
简单按键api
端口:16735
格式如下:
下面这是测试的一些功能:
- "power" => 'KEYPRESSES:116',
- "vol+" => "KEYPRESSES:115",
- "vol-" => "KEYPRESSES:114",
- "menu" => "KEYPRESSES:139",
- "back" => "KEYPRESSES:48",
- "pause" => "KEYPRESSES:49",
- "paly" => "KEYPRESSES:49",
- "down" => "KEYPRESSES:38",
- "up" => "KEYPRESSES:36",
- "left" => "KEYPRESSES:50",
- "right" => "KEYPRESSES:37",
- "home" => "KEYPRESSES:35",
复制代码
我用的是复杂指令,可以实现快速关机。测试很简单,找一个通讯测试助手一类的软件,电脑和投影仪在一个局域网内,用UDP Client填写投影仪的IP地址及端口号,然后发送复杂或者简单指令,就能实现控制。测试可用的话这步也就成功了
======================分割线=====================
三、ESP32开发板编程
我使用的是Arduino,先贴一下主程序代码,基本都注释了,如果有问题发帖吧
- #include <WiFi.h> //默认,加载WIFI头文件
- #include "PubSubClient.h" //默认,加载MQTT库文件
- #include <WiFiUdp.h> //引用以使用UDP
- #include "ESP32BLEAdvertise.h" //引用蓝牙广播头文件
- //********************需要修改的部分*******************//
- const char* ssid = "XXXX"; //修改,你的路由去WIFI名字
- const char* password = "XXXXXXXX"; //你的WIFI密码
- #define ID_MQTT "XXXXXXXXXXXXXX" //用户私钥,控制台获取
- const char* topic = "XXXXXXXXXXXX"; //主题名字,可在巴法云控制台自行创建,名称随意
- const int B_led = 2; //单片机LED引脚值,D系列是NodeMcu引脚命名方式,其他esp8266型号将D2改为自己的引脚
- bool Turned = false;;
- //**************************************************//
- const char* mqtt_server = "bemfa.com"; //默认,MQTT服务器
- const int mqtt_server_port = 9501; //默认,MQTT服务器
- WiFiClient espClient;
- PubSubClient client(espClient);
- SimpleBLE bleadv;
- //灯光函数及引脚定义
- void turnOn();
- void turnOff();
- //********************UDP按键信息关机*****************//
- WiFiUDP Udp;
- IPAddress remote_IP(192, 168, 3, 27);// 自定义远程监 IP 地址
- unsigned int remoteUdpPort = 16735; // 简单指令端口
- unsigned int remoteUdpPortFZ = 16750; // 复杂令端口
- const char* Keyword = "KEYPRESSES:116"; //简单指令:关机
- const char* KeywordFZ = {"{"action":20000,"controlCmd":{"delayTime":0,"mode":6,"time":0,"type":0},"msgid":"2"}"}; //复杂指令:快速关机
- //**************************************************//
- void setup_wifi() {
- delay(10);
- Serial.println();
- Serial.print("Connecting to ");
- Serial.println(ssid);
- WiFi.begin(ssid, password);
- while (WiFi.status() != WL_CONNECTED) {
- delay(500);
- Serial.print(".");
- }
- Serial.println("");
- Serial.println("WiFi connected");
- Serial.println("IP address: ");
- Serial.println(WiFi.localIP());
- }
- void callback(char* topic, byte* payload, unsigned int length) {
- Serial.print("Topic:");
- Serial.println(topic);
- String msg = "";
- for (int i = 0; i < length; i++) {
- msg += (char)payload[i];
- }
- Serial.print("Msg:");
- Serial.println(msg);
- if (msg == "on") {//如果接收字符on,亮灯并打开投影
- turnOn();//开启函数
- Turned = true;
- } else if (msg == "off") {//如果接收字符off,关灯并关闭投影
- turnOff();//关闭函数
- Turned = false;
- }
- msg = "";
- }
- void reconnect() {
- // Loop until we're reconnected
- while (!client.connected()) {
- Serial.print("Attempting MQTT connection...");
- // Attempt to connect
- if (client.connect(ID_MQTT)) {
- Serial.println("connected");
- Serial.print("subscribe:");
- Serial.println(topic);
- //订阅主题,如果需要订阅多个主题,可发送多条订阅指令client.subscribe(topic2);client.subscribe(topic3);
- client.subscribe(topic);
- } else {
- Serial.print("failed, rc=");
- Serial.print(client.state());
- Serial.println(" try again in 5 seconds");
- // Wait 5 seconds before retrying
- delay(5000);
- }
- }
- }
- void setup() {
- pinMode(B_led, OUTPUT); //设置引脚为输出模式
- digitalWrite(B_led, LOW);//默认引脚上电高电平
- Serial.begin(115200); //设置波特率115200
- setup_wifi(); //设置wifi的函数,连接wifi
- client.setServer(mqtt_server, mqtt_server_port);//设置mqtt服务器
- client.setCallback(callback); //mqtt消息处理
- }
- void loop() {
- int i = 1;
- if (!client.connected()) {
- reconnect();
- }
- else
- {
- if (Turned)
- {
- bleadv.begin();//初始化蓝牙名
- uint8_t data[] = {0x46, 0x00, 0x46, 0x17, 0x03, 0xef, 0xb2, 0x24, 0x40, 0xff, 0xff, 0xff, 0x30, 0x43, 0x52, 0x4b, 0x54, 0x4d}; //蓝牙广播内容
- bleadv.advertise(data, 18);
- delay(5000);
- }
- else
- {
- bleadv.end();
- }
- }
- client.loop();
- }
- //打开投影
- void turnOn() {
- digitalWrite(B_led, HIGH);
- }
- //关闭投影
- void turnOff() {
- digitalWrite(B_led, LOW);
- Udp.beginPacket(remote_IP, remoteUdpPortFZ);//配置远端ip地址和端口
- String str_cnt(KeywordFZ);
- Udp.print(str_cnt);//把数据写入发送缓冲区
- Udp.endPacket();//发送数据
- }
复制代码
好了,到此就可以接入巴法控制了。怎么加入米家就不用说了吧~
![]()
相关阅读:
怎样用小爱音箱控制电视 用小爱音箱控制电视播放任意影视
|