『瀚思彼岸』» 智能家居技术论坛

 找回密码
 立即注册
楼主: XCray

[新奇玩法] (多个)蓝牙网关 TTL->MQTT,支持任意米家蓝牙设备接入HA/NR

  [复制链接]

0

主题

17

帖子

125

积分

注册会员

Rank: 2

积分
125
金钱
108
HASS币
0
发表于 2024-10-31 11:21:59 | 显示全部楼层
巴法云是云端了,可能会影响速度。亮度,色温不可以触发,但是可以由米家读取,所以用一个on off信号触发米家,然后米家读取亮点和色温判断具体指令和传递信息
因此如果HA可以通过蓝牙网关来设置色温亮度,或许是可行的。
今天去买ESP32了
回复

使用道具 举报

0

主题

17

帖子

125

积分

注册会员

Rank: 2

积分
125
金钱
108
HASS币
0
发表于 2024-11-11 00:12:21 | 显示全部楼层
本帖最后由 凡不了 于 2024-11-11 00:15 编辑

刚刚到手ESP32,先用ESPHome简单试了一下,接了一个灯(switch)和开关(binary_sensor),正常工作。然后开始我的目标之路,下载了一楼的mqttl.zip,解压缩了2个文件,
***文件mqttl.yaml***:
·      根据我个人设备情况,修改了wifi_ssid,wifi_password,ota_password,mqtt_server
·         我用的设备是ESP32,相应修改
  platform: ESP32
  board: esp32dev
上述platform和board设置已经在前面用switch和binary-sensor测试过,没有问题

***文件mqttl.h***:
由于原来C++代码是基于ArduinoJson 5,现在新的版本ArduinoJson 6不支持了,编译无法通过,因此我参考了相关资料,更改如下:
    // 下面的是老版本ArduinoJson 5
    //StaticJsonBuffer<500> jsonBuffer;
    // JsonObject&jsonData = jsonBuffer.parseObject(json);   // json 解析失败
    //if(!jsonData.success()){
    //   ESP_LOGD(TAG, "Json parse failed.string:%s", json);
    //   return;
    // }


    // 新版本V6,参考:https://arduinojson.org/v6/doc/upgrade/
   StaticJsonDocument<500> doc;
   DeserializationError error = deserializeJson(doc, json);

    // json 解析失败
    if(error){
      ESP_LOGD(TAG,"Json parse failed. string:%s", json);
      return;
}

JsonObject jsonData =doc.as<JsonObject>();   

当时我最后没有成功,显示的是Offline状态,我的环境为:
-----------------------------------------------------------------------------------------------------------------
硬件:R5S
软件:iStoreOS,Docker安装了MQTT(mosquitto)和HomeAssistant;
其中MQTT已经用其它程序测试过,是正常的,能否请大佬帮指点一下,到底出错在什么地方?
==================================================================
更改后的mqttl.h#pragma once=============================================================================
#include "esphome.h"
static const char *TAG = "mijiaBleMessage";

class mijiaBleMessage : public Component, public CustomMQTTDevice {
public:
  void setup() override {
    Serial.begin(115200);
  }
  void loop() override
  {
    while(Serial.available()){
      this->readline_(Serial.read());
    }
  }
protected:
  // 存储每行 UART 消息
  std::vector<char> rx_message_;

  // 获取 json 字符
  char * getJson_(char * inChar){
    char *json = strstr(inChar,"{");
    if (!json) {return NULL;}
    char *pch=strrchr(json,'}');
    if (pch)
    {
      json[pch-json+1] = 0;
      return json;
    } else {
      return NULL;
    }
  }

  // 获取每行消息
  void readline_(int c)
  {
    if (c > 0){
      switch (c) {
        case '\n':
          break;
        case '\r':
        {
          // 字符串终止符
          rx_message_.push_back(0x00);
          // 解析 rx 的消息
          this->handle_();
          // 清除缓冲区
          this->rx_message_.clear();
          break;
        }
        default:
          this->rx_message_.push_back(c);
      }
    }
  }

  // 消息处理
  void handle_(){
    char *data = &rx_message_[0];

    // 判断是否蓝牙事件
    if(!strstr(data,"_async.ble_event")){
      return;
    }
    char *json = getJson_(data);
    if(!json){
      ESP_LOGD(TAG, "Json not found: %s", data);
      return;
    }
    ESP_LOGD(TAG, "[bluetooth event] %s", data);
    // 蓝牙事件 json 例子:
    // {"id":1518998071,"method":"_async.ble_event","params":{"dev":{"did":"1011078646","mac":"AA:BB:CC

                               
登录/注册后可看大图
D:EE:FF","pdid":794},"evt":[{"eid":7,"edata":"0036f6e45e"}],"frmCnt":97,"gwts":2362}}
   
//修改部分------------------------------------------------------------

// 下面的是老版本ArduinoJson 5
    // StaticJsonBuffer<500> jsonBuffer;
    // JsonObject& jsonData = jsonBuffer.parseObject(json);    // json 解析失败
    // if(!jsonData.success()){
    //   ESP_LOGD(TAG, "Json parse failed. string:%s", json);
    //   return;
    // }

  
    // 新版本V6 https://arduinojson.org/v6/doc/upgrade/
    StaticJsonDocument<500> doc;
    DeserializationError error = deserializeJson(doc, json);
   
    // json 解析失败
    if(error){
      ESP_LOGD(TAG, "Json parse failed. string:%s", json);
      return;
    }
    JsonObject jsonData = doc.as<JsonObject>();   

    // 获取 did
    JsonObject dev = jsonData["params"]["dev"];
    const char *did = dev["did"];
    if(!did){
      ESP_LOGD(TAG, "did is not found.");
      return;
    }

    // 遍历数组获取edata与eid
    if(!jsonData["params"]["evt"].is<JsonArray>()){
      ESP_LOGD(TAG, "evt is not an array.");
      return;
    }

    JsonArray arr = jsonData["params"]["evt"];
    for (JsonObject value : arr) {
        const char *eid = value["eid"];
        char edata[20] = {0};
        strcpy(edata, value["edata"]);

        if (strlen(edata) == 0) {
            ESP_LOGD(TAG, "edata is not found.");
            break;
        }

        if (strlen(edata) % 2 == 1) {
            ESP_LOGD(TAG, "length error! edata corrupt!");
        }

        this->reverse_(edata);
        this->mqttPublish_(did, eid, edata);
    }

  }

  // 两字节高低转换
  void reverse_(char *inChar){
    size_t l = strlen(inChar);
    for (int i = 0,j=l-2; i<j; i++,j=j-3)
    {
      char a = inChar;
      inChar = inChar[j];
      inChar[j] = a;
      i++;
      j++;
      char b = inChar;
      inChar = inChar[j];
      inChar[j] = b;
    }
  }

  // 发送 mqtt 消息
  //void mqttPublish_(const char *deviceID, const char *payload){
  //  char topic[80];
  //  sprintf(topic,"mqttl/%s/evt",deviceID);
  //  publish(std::string(topic), std::string(payload));
  //}

  // 发送 mqtt 消息
  void mqttPublish_(const char *deviceID, const char *eid, const char *edata){
    char topic[80];
    sprintf(topic,"mqttl/%s/%s",deviceID,eid);
    publish(std::string(topic), std::string(edata));
  }
};





回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|Hassbian

GMT+8, 2024-12-25 13:56 , Processed in 0.078427 second(s), 22 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表