Преамбула: по неким необъяснимым причинам возникло желание пробрасывать свет из HomeAssistant в HomeKit без участия HA. Потому что родная интеграция НА для HomeKit хоть и хорошая, но почему-то хромает, например, может пересоздать устройство или задублировать его. И если со всеми выключателями, которые живут своей жизнью, через MQTT все было просто, то вот со светом (а у меня большинство ламп и лент от Yeelight) - пришлось посидеть, подумать. Зачем пробрасывать лампы не напрямую, а из НА? Ну потому что они все равно там есть, и потому что в результате получается некий универсальный интерфейс к лампам разных производителей. Не претендую на идеал, но, по крайней мере, flow не занимает всю страницу, и при дублировании нужно поправить всего две ноды для тех, кто дочитает до середины, или одну - для тех, кто дочитает до конца :)
В общем, поехали.
var characteristic = {}; if(msg.data.new_state.state === 'on') { characteristic.On = true; if(msg.data.new_state.attributes.hasOwnProperty("brightness") && msg.data.new_state.attributes.brightness !== undefined) { characteristic.Brightness = parseInt((msg.data.new_state.attributes.brightness / 2.55).toFixed()) || 10; } else { characteristic.Brightness = 100; } if(msg.data.new_state.attributes.hasOwnProperty("hs_color") && msg.data.new_state.attributes.hs_color[0] !== undefined) { characteristic.Hue = msg.data.new_state.attributes.hs_color[0]; } else { characteristic.Hue = 0; } if(msg.data.new_state.attributes.hasOwnProperty("hs_color") && msg.data.new_state.attributes.hs_color[1] !== undefined) { characteristic.Saturation = msg.data.new_state.attributes.hs_color[1]; } else { characteristic.Saturation = 0; } var brg_name = msg.topic '.brightness'; var sat_name = msg.topic '.saturation'; var hue_name = msg.topic '.hue' flow.set(brg_name, characteristic.Brightness); flow.set(sat_name, characteristic.Saturation); flow.set(hue_name, characteristic.Hue); } else { characteristic.On = false; } msg.payload = characteristic; return msg;
Кстати, я очень не люблю использовать "постоянные" переменные, например, если скопировать ноду, в которой пишется что-то в переменную test, у нас будет две ноды, работающие с одной переменной. А значит, в какой-то момент результаты могут быть неожиданными. Поскольку я понял, что без flow переменных все-таки не обойтись, то я решил сделать так, чтобы имена переменных были сами переменными, в результате, для каждой лампы имена будут уникальными.
Имя переменной, в которой хранится значение яркости в данном случае, например, будет light.bed_strip.brightness. При другом имени лампочки в НА - будет другое имя. Но этим можно голову не забивать, к ним обращаться не требуется.
Ноды выключения и включения света - это ноды call service и выглядят идентично, за исключеним вызываемого сервиса. На всякий случай все равно их здесь приведу, хотя думаю, они всем известны.
Основной интерес представляют оставшиеся две с половиной ноды, а именно, function, join и call service.
var brg_name = msg.topic '.brightness'; var sat_name = msg.topic '.saturation'; var hue_name = msg.topic '.hue' var new_val = {}; if(msg.payload.Brightness >= 0) { new_val.brightness = msg.payload.Brightness; flow.set(brg_name, msg.payload.Brightness); new_val.saturation = flow.get(sat_name); new_val.hue = flow.get(hue_name); } if(msg.payload.Hue >= 0) { new_val.brightness = flow.get(brg_name); new_val.saturation = flow.get(sat_name); new_val.hue = msg.payload.Hue; flow.set(hue_name, msg.payload.Hue); } if(msg.payload.Saturation >= 0) { new_val.brightness = flow.get(brg_name); new_val.saturation = msg.payload.Saturation; flow.set(sat_name, msg.payload.Saturation); new_val.hue = flow.get(hue_name); } new_val.data = { "brightness_pct" : new_val.brightness } if(new_val.hue !== undefined && new_val.saturation !== undefined) { new_val.data.hs_color = [new_val.hue, new_val.saturation]; } msg.payload = new_val; return msg;
На этом в общем-то все. Спасибо всем, кто дочитал до этого места. Вы уже можете повторить данные шаги и пробросить одну свою лампочку в НК. Если у вас их две, тогда скопируйте всю цепочку, поправьте имена в первой ноде и в нодах вызова сервиса, переименуйте ноду НК для второй лампы и вот их у вас уже станет две.
Но если у вас еще есть время и желание, давайте порассуждаем над такой чисто гипотетической ситуацией, когда у кого-то лампочек не одна и даже не две? Я понимаю, конечно, что это ситуация чисто гипотетическая, ну у кого может быть три лампы, тем более умных, не говоря уже о большем количестве? Но вдруг?
И вот на этом уже действительно все. Теперь, когда нужно будет что-то поправить, достаточно будет открыть одну ноду, а добавление новой лампы сводится к копированию ноды НК с обоими линками и внесением правок в два поля внутри нее.
Спасибо что дочитали, надеюсь все у вас получится.
А если установлен hass.io в Docker, вНутри HA стоит NodeRed. Можно ли так же устройства пробросить в home kit или создать виртуальные в среде nodered? Какой нужен пакет для homekit в Nodered, на сколько я понял это homekit-bridged?
По поводу hass.io не знаю, не пробовал. Проще всего попробовать - это создать в node-red какой-нибудь выключатель и пощелкать им, привязав ноды дебага к выходам. Если сообщения из НК будут приходить - то значит все ок.
Только следует учитывать, что если в самом НА включен homekit то может не получиться, они конфликтуют "по портам", устройство то создается, а вот информация о действиях с ним в node-red не поступает.
попробую все что можно))
в Hass.io (в Docker) заработало, конфликтов с интеграцие homekit hass нет, все что нужно пробрасывается нормально)
Был мой косяк: не дал имя мосту (в настройках nodered)