Настройка правильной реакции на MQTT в Rules

Добрый день! Есть виртуальное устройство для адаптации работы шлюза кондиционеров Intesis с Home Assistant. В шлюзе есть отдельная кнопка включения/выключения, а в HA выключение реализовано через как бы режим работы “выключено”.

В виртуальном устройстве есть топик-управление кондиционером. Когда Home Assistant шлёт туда уставку режима, rules должны отработать и выполнить определённые действия.

У меня это реализовано через whenChanged. Оно ожидаемо работает при изменении топика, но может сложиться ситуация, когда кондиционер был включен из HA (подана команда “охлаждение”), затем выключен с физического пульта, соответственно, топик уставки из Home Assistant остаётся неизменённым (“охлаждение”). При попытке включить его из HA, HA отправит в топик команду “охлаждать”, но поскольку там уже есть значение “охлаждать”, правило не сработает, и кондиционер останется выключенным.

Если заменить whenChanged на trackMqtt, при отправке такого же значения, как уже есть в топике, правило срабатывает, но мы получаем другую проблему. Допустим, кондиционер был включен из HA (подана команда “охлаждение”), затем выключен с физического пульта, соответственно, топик уставки из Home Assistant остаётся неизменённым (“охлаждение”). При перезагрузке WB, или правил, или чего-нибудь ещё, сработает правило, и включит кондиционер на охлаждение, хотя новой команды от HA не приходило.

Соответственно вопрос, какую функцию использовать, и как избежать описанных выше проблем?

Заранее спасибо, правила прикрепляю.

whenChanged
//Ver. 0.1
var intesis_name = "IntesisboxINMBSDAI001R000_14"; //Устройство, на которое ориентируемся

defineVirtualDevice(intesis_name + "_virt_mode", {
    title: intesis_name + "_virt_mode" ,
    cells: {
      mode_state_topic: {
        title: "mode_state_topic",
	    type: "text",
	    value: "unknown"
	    },
      mode_command_topic: {
        title: "mode_command_topic",
	    type: "text",
	    value: "unknown",
        readonly : false
	    },
    }
})

defineRule({
  whenChanged: [intesis_name + "/Power", intesis_name + "/Mode", "system/Current uptime"],
  then: function () {
      if (dev[intesis_name + "/Power"] == false){
        dev[intesis_name + "_virt_mode"]["mode_state_topic"] = "off"
      } else if (dev[intesis_name + "/Mode"] == 0){
        dev[intesis_name + "_virt_mode"]["mode_state_topic"] = "auto"
      } else if (dev[intesis_name + "/Mode"] == 1){
        dev[intesis_name + "_virt_mode"]["mode_state_topic"] = "heat"
      } else if (dev[intesis_name + "/Mode"] == 2){
        dev[intesis_name + "_virt_mode"]["mode_state_topic"] = "dry"
      } else if (dev[intesis_name + "/Mode"] == 3){
        dev[intesis_name + "_virt_mode"]["mode_state_topic"] = "fan_only"
      } else if (dev[intesis_name + "/Mode"] == 4){
        dev[intesis_name + "_virt_mode"]["mode_state_topic"] = "cool"
      }
    }
  }
)

defineRule({
  whenChanged: [intesis_name + "_virt_mode/mode_command_topic"],
  then: function () {
      if (dev[intesis_name + "_virt_mode"]["mode_command_topic"] == "off"){
        dev[intesis_name + "/Power"] = false
      } else if (dev[intesis_name + "_virt_mode"]["mode_command_topic"] == "auto"){
        dev[intesis_name + "/Power"] = true
        dev[intesis_name + "/Mode"] = 0
      } else if (dev[intesis_name + "_virt_mode"]["mode_command_topic"] == "heat"){
        dev[intesis_name + "/Power"] = true
        dev[intesis_name + "/Mode"] = 1
      } else if (dev[intesis_name + "_virt_mode"]["mode_command_topic"] == "dry"){
        dev[intesis_name + "/Power"] = true
        dev[intesis_name + "/Mode"] = 2
      } else if (dev[intesis_name + "_virt_mode"]["mode_command_topic"] == "fan_only"){
        dev[intesis_name + "/Power"] = true
        dev[intesis_name + "/Mode"] = 3
      } else if (dev[intesis_name + "_virt_mode"]["mode_command_topic"] == "cool"){
        dev[intesis_name + "/Power"] = true
        dev[intesis_name + "/Mode"] = 4
      }
    }
  }
)
trackMqtt
//Ver. 0.1
var intesis_name = "IntesisboxINMBSDAI001R000_14"; //Устройство, на которое ориентируемся

defineVirtualDevice(intesis_name + "_virt_mode", {
    title: intesis_name + "_virt_mode" ,
    cells: {
      mode_state_topic: {
        title: "mode_state_topic",
	    type: "text",
	    value: "unknown"
	    },
      mode_command_topic: {
        title: "mode_command_topic",
	    type: "text",
	    value: "unknown",
        readonly : false
	    },
    }
})

defineRule({
  whenChanged: [intesis_name + "/Power", intesis_name + "/Mode", "system/Current uptime"],
  then: function () {
      if (dev[intesis_name + "/Power"] == false){
        dev[intesis_name + "_virt_mode"]["mode_state_topic"] = "off"
      } else if (dev[intesis_name + "/Mode"] == 0){
        dev[intesis_name + "_virt_mode"]["mode_state_topic"] = "auto"
      } else if (dev[intesis_name + "/Mode"] == 1){
        dev[intesis_name + "_virt_mode"]["mode_state_topic"] = "heat"
      } else if (dev[intesis_name + "/Mode"] == 2){
        dev[intesis_name + "_virt_mode"]["mode_state_topic"] = "dry"
      } else if (dev[intesis_name + "/Mode"] == 3){
        dev[intesis_name + "_virt_mode"]["mode_state_topic"] = "fan_only"
      } else if (dev[intesis_name + "/Mode"] == 4){
        dev[intesis_name + "_virt_mode"]["mode_state_topic"] = "cool"
      }
    }
  }
)

trackMqtt("/devices/IntesisboxINMBSDAI001R000_14_virt_mode/controls/mode_command_topic", function(message){
      if (dev[intesis_name + "_virt_mode"]["mode_command_topic"] == "off"){
        dev[intesis_name + "/Power"] = false
      } else if (dev[intesis_name + "_virt_mode"]["mode_command_topic"] == "auto"){
        dev[intesis_name + "/Power"] = true
        dev[intesis_name + "/Mode"] = 0
      } else if (dev[intesis_name + "_virt_mode"]["mode_command_topic"] == "heat"){
        dev[intesis_name + "/Power"] = true
        dev[intesis_name + "/Mode"] = 1
      } else if (dev[intesis_name + "_virt_mode"]["mode_command_topic"] == "dry"){
        dev[intesis_name + "/Power"] = true
        dev[intesis_name + "/Mode"] = 2
      } else if (dev[intesis_name + "_virt_mode"]["mode_command_topic"] == "fan_only"){
        dev[intesis_name + "/Power"] = true
        dev[intesis_name + "/Mode"] = 3
      } else if (dev[intesis_name + "_virt_mode"]["mode_command_topic"] == "cool"){
        dev[intesis_name + "/Power"] = true
        dev[intesis_name + "/Mode"] = 4
      }
});

Добрый день!

Данное видео должно ответить на все ваши вопросы:
Ссылка на видео.

Дополнительно рекомендую ознакомиться с:

Если после просмотра и изучения материалов останутся вопросы, дайте знать — я готов помочь!

Добрый день, удалось ли решить вопрос?

Добрый, в процессе