Открыть меню
Toggle preferences menu
Открыть персональное меню
Вы не представились системе
Your IP address will be publicly visible if you make any edits.

Создание кастомного шаблона на примере ESP

Материал из Sprut.hub Wiki

Для начала необходимо установить на ESP прошивку, которая поддерживает MQTT отправку сообщений. Это может быть:

  • ESPhome
  • Tasmota
  • Esp easy
  • WiFi iot

Теперь в настройках устройства указываем в качестве MQTT брокера Spruthub.

  • IP брокера - IP вашего хаба
  • Логин - оставяем пустой
  • Пароль - оставляем пустой
  • Порт - 44444

Если смотреть на примере ESPhome, то настройка будет выглядеть так:

mqtt: 
  broker: 192.168.2.79
  port: 44444 
  topic_prefix: esphome 
  discovery: false

topic_prefix указывается, что бы в дальнейшем все устройства искать по одному шаблону а не вычленять нужные топики из корня.

Затем, надо узнать структуру MQTT топиков, которые типичны для прошивки, которую вы выбрали. Сделать это можно либо в мануале по соответсвующей прошивке, либо подключившись к SprutHub брокеру MQTT в приложении MqttExplorer.


И даже в логах самого ESPhome можно будет увидеть топики, которые используются для управления:

[16:35:24][C][mqtt.switch:038]: MQTT Switch 'Heat': 
[16:35:24][C][mqtt.switch:039]: State Topic: 'esphome/switch/heat/state' 
[16:35:24][C][mqtt.switch:039]: Command Topic: 'esphome/switch/heat/command'

Шаблон для хаба

Теперь можно перейти к более сложному - созданию собственного шаблона, который мы потом сможем добавить на хаб в соответствии с инструкцией в папку, где должны располагаться MQTT шаблоны

В новом шаблоне, который мы позаимствовали у подобного устройства WirenBoard, мы удаляем строчку с "catalogId" потому как устройства которое мы добавляем скорее всего в каталоге нет. Топики для обнаружения и управления меняем на свои.

Если вы не знаете куда "приземлить" тот или иной параметр, у хаба есть справочник, в котором перечислены все поддерживаемые сервисы и характеристики.

В результате у меня получилось как то так:

{
  "manufacturer": "Itead",
  "model": "Sonoff Basic",
  "modelId": "esphome/switch/(.*)/state",
  "services": [
    {
      "type": "Switch",
      "characteristics": [
        {
          "type": "On",
          "link": {
            "type": "String",
            "topicGet": "esphome/switch/(1)/state",
            "topicSet": "esphome/switch/(1)/command",
            "map": {
              "false": "OFF",
              "true": "ON"
            }
          }
        }
      ]
    }
  ]
}

Разберем по порядку.

"manufacturer": "Itead"

Тут пишем производителя устройства.

"model": "Sonoff Basic"

Тут пишем модель устройства.

"modelId": "esphome/switch/(.*)/state"

Это топик для определения самого устройства. Что бы не делать шаблон на каждое новое устройство достаточно правильно задать данный параметр. В нем можно использовать регулярные выражения. В моем случае ищется вхождение любой фразы в топике esphome/switch. Фраза эта запоминается и используется дальше.

"services"

Описываем сервисы, которые будут использоваться в устройстве.

"type": "Switch"

Указываем тип устройства, который в Spruthub стандартизирован гайдлайнами HomeKit

"characteristics"

Описываем характеристики добавляемого устройства

"type": "String"

Изменяем тип передаваемых и принимаемых данных для управления устройством. Это актуально для ESPhome, потому что топики управляются сообщениями ON/OFF, но об этом дальше.

"topicGet": "esphome/switch/(1)/state"

Топик, в котором считывается текущее состояние устройства.

"topicSet": "esphome/switch/(1)/command"

Топик которым управляется устройство. В случае ESPhome ему надо передать ON или OFF

"map"

А тут самое интересное, о чем я писал в начале. Так как ESPhome надо передать для управления ON или OFF, а хаб передает true или false, нам необходимо переопределить эти параметры, что мы и делаем ниже:

"false": "OFF"
"true": "ON"

Еще один, но более сложный пример. Шаблон основан на шаблоне WirenBoard WB-MSW.json и добавляет в хаб сенсоры, подключенные к esphome:

{
  "name": "Набор датчиков",
  "manufacturer": "ESPhome",
  "model": "Esp sensor",
  "modelId": "esphome/sensor/(mh-z.*)_temperature/state",
  "services": [
    {
      "type": "TemperatureSensor",
      "characteristics": [
        {
          "type": "CurrentTemperature",
          "link": {
            "type": "Float",
            "topicGet": "esphome/sensor/(1)_temperature/state"
          }
        }
      ]
    },
    {
      "type": "HumiditySensor",
      "characteristics": [
        {
          "type": "CurrentRelativeHumidity",
          "link": {
            "type": "Float",
            "topicGet": "esphome/sensor/(1)_humidity/state"
          }
        }
      ]
    },
    {
      "type": "AirQualitySensor",
      "data": {
        "Logic": {
          "selected": "AirQualityFromVOCDensity"
        }
      },
      "characteristics": [
        {
          "type": "VOCDensity",
          "link": {
            "type": "Integer",
            "topicGet": "esphome/sensor/(1)_voc/state"
          }
        }
      ]
    },
    {
      "type": "CarbonDioxideSensor",
      "data": {
        "Logic": {
          "selected": "CarbonDioxideDetectedFromCarbonDioxideLevel"
        }
      },
      "characteristics": [
        {
          "type": "CarbonDioxideLevel",
          "link": {
            "type": "Integer",
            "topicGet": "esphome/sensor/(1)_co2_value/state"
          }
        }
      ]
    },
    {
      "type": "LightSensor",
      "characteristics": [
        {
          "type": "CurrentAmbientLightLevel",
          "link": {
            "type": "Float",
            "topicGet": "esphome/sensor/(1)_light_level/state"
          }
        }
      ]
    },
    {
      "type": "MotionSensor",
      "characteristics": [
        {
          "type": "MotionDetected",
          "link": {
            "type": "Integer",
            "topicGet": "esphome/sensor/(1)_motion_level/state",
            "map": {
              "0": "OFF",
              "1": "ON"
            }
          },
          "data": {
            "OnAfterLevel": 200
          }
        }
      ]
    },
    {
      "type": "ContactSensor",
      "characteristics": [
        {
          "type": "ContactSensorState",
          "link": {
            "type": "String",
            "topicGet": "esphome/sensor/(1)_contact/state",
            "map": {
              "0": "OFF",
              "1": "ON"
            }
          }
        }
      ]
    }
  ]
}

Можно заметить две вещи.

  1. modelId используется для идентификации однотипных устройств. Если правильно задать имена сенсоров в ESPhome, то эта уловка сработает и вы получите универсальный шаблон для всех сенсоров на этой прошивке.
  2. Для датчика CO2 и датчика VOC используется виртуальная логика определения превышения допустимого уровня, в результате чего в HomeKit вы получите бинарный датчик, который будет срабатывать при заданном вами пороге.