Добрый день! Есть виртуальное устройство для адаптации работы шлюза кондиционеров 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
}
});