Глядя на красивый и удобный вывод информации о погоде у Яндекса и у MSN
Захотелось тоже самое сделать у себя, чтобы на планшете у входной двери отображалась такая информация (кроме непосредственно управлением умным домом).
Не уверен есть ли необходимая информация в API (думаю, что свободного вообще нет), решил автоматизировать получение этой полезной информации через плагин к HA — Node-RED. Предполагается, что он у вас уже установлен.
Весь код на NR будет в самом конце статьи.
В итоге «графически» алгоритмы получения информации с сайта Yandex выглядит так:

С сайта MSN так:

Первым делом нам нужно в html коде сайта Яндекс.Погоды найти селектор, в который выводится нужная нам информация:

Селектором оказывается div c классом title-icon__text
В рабочую область с панели инструментов кидаем узел http request и настраиваем его на запрос по url яндекс погоды, подставляя координаты из HA, он нам нужен для непосредственного GET запроса на сайт Яндекса.

Я еще добавил, на всякий случай, User agent, так как за частые однотипные запросы Яндекс отдает страницу с капчей.

Следом кидаем узел отвечающий за обработку данных полученных с предыдущего узла, в поле Selector указываем найденный ранее селектор. В Output указываем что нам нужен только чистый текст.


В итоге по всем найденным селекторам будет сформирован поток данных, который нужно объединить в одну строку для вывода в будущий виртуальный датчик HA, делаем это с помощью узла Join
И последний важный узел это виртуальный датчик Home Assistant, куда будет отправлена сформированная ранее строка.


Тут важный параметр Entity config, нужно выбрать Add new ha-entity, после деплоя кода в области видимости сенсоров HA появится новый с транслитерированным названием.
Как вы наверно заметили, на первой картинке гораздо больше узлов, их я специально пропустил чтобы не загромождать статью. Они отвечают за периодичность запросов и дебаг, а также я добавил второй сенсор, у которого другой селектор.
В итоге в панели управления умным домом эта информация будет выглядеть примерно так:

Для получения информации с сайта MSN все очень похоже, за исключением того что «удобного селектора» я не нашел; само название параметра и его значение выбираются двумя разными селекторами:

Это div.lifeIndexBarTitle-E1_1 и div.lifeIndexBarSummary-E1_1 мне пришлось их объединять в один поток с помощью стороннего узла Merge (он ставится в пару кликов в NR: Menu, Manage palette, Install).

Так как два разных потока формируют результат асинхронно, нужен этот узел Merge, который после получения первого сигнала ждет (по умолчанию) две секунды для получения всех остальных, а потом объединенный поток отправляет дальше.

А дальше для нашего нового виртуального сенсора, нужно из этого большого объекта (внутри два потока) получить строку для вывода, для этого нам нужен узел Function (который может выполнять любой код на JS):

var array1 = msg.payload[0].payload; var array2 = msg.payload[1].payload; var newArray = ""; for (var i = 0; i < array1.length && i < array2.length; i++) { newArray += array1[i] + ": " + array2[i]+"\r\n"; } msg.payload = newArray; return msg;
Пример вывода нового сенсора от MSN:

И результат полностью:

Коды ниже можно импортировать непосредственно в Node-RED, скопировав в буфер и вставив.
Код для Яндекс
[{"id":"ad1d92815f2810e3","type":"tab","label":"Осадки от Yandex","disabled":false,"info":"","env":[]},{"id":"91b656e34bb36636","type":"inject","z":"ad1d92815f2810e3","name":"каждый 15 минут","props":[{"p":"payload"}],"repeat":"900","crontab":"","once":true,"onceDelay":"5","topic":"","payload":"","payloadType":"date","x":130,"y":60,"wires":[["c2a6fc2cee844617","d147070d4e892acb"]]},{"id":"c2a6fc2cee844617","type":"delay","z":"ad1d92815f2810e3","name":"Случайная задержка","pauseType":"random","timeout":"30","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"10","randomLast":"50","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":380,"y":60,"wires":[["33244b375f9536ba"]]},{"id":"d147070d4e892acb","type":"http request","z":"ad1d92815f2810e3","name":"Запрос осадков сейчас","method":"GET","ret":"txt","paytoqs":"ignore","url":"https://yandex.ru/pogoda/maps/nowcast?lat={{states.zone.home.attributes.latitude}}&lon={{states.zone.home.attributes.longitude}}","tls":"","persist":false,"proxy":"","insecureHTTPParser":false,"authType":"","senderr":false,"headers":[{"keyType":"other","keyValue":"user-agent","valueType":"other","valueValue":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36"}],"x":170,"y":160,"wires":[["b83ef7431f50c2b9","088f18771b04025a"]]},{"id":"b83ef7431f50c2b9","type":"html","z":"ad1d92815f2810e3","name":"Выбираем строку с прогнозом","property":"payload","outproperty":"payload","tag":"div.weather-maps-fact__nowcast-alert","ret":"text","as":"single","x":430,"y":160,"wires":[["d5f87c9849faccbe"]]},{"id":"33244b375f9536ba","type":"http request","z":"ad1d92815f2810e3","name":"Запрос осадков на неделю","method":"GET","ret":"txt","paytoqs":"ignore","url":"https://yandex.ru/pogoda/?lat={{states.zone.home.attributes.latitude}}&lon={{states.zone.home.attributes.longitude}}","tls":"","persist":false,"proxy":"","insecureHTTPParser":false,"authType":"","senderr":false,"headers":[],"x":160,"y":260,"wires":[["725a40f983bcb9ed","088f18771b04025a"]]},{"id":"725a40f983bcb9ed","type":"html","z":"ad1d92815f2810e3","name":"Выбираем строку с прогнозом","property":"payload","outproperty":"payload","tag":"div.title-icon__text","ret":"text","as":"single","x":430,"y":260,"wires":[["faec5435d1fd53df"]]},{"id":"088f18771b04025a","type":"html","z":"ad1d92815f2810e3","name":"Попали на SmartCaptcha?","property":"payload","outproperty":"payload","tag":"span.Text_typography_headline-s","ret":"text","as":"single","x":420,"y":360,"wires":[["079500ac2cd1bdb3"]]},{"id":"079500ac2cd1bdb3","type":"debug","z":"ad1d92815f2810e3","name":"SmartCaptcha","active":true,"tosidebar":false,"console":false,"tostatus":true,"complete":"payload","targetType":"msg","statusVal":"payload","statusType":"auto","x":660,"y":360,"wires":[]},{"id":"0760bb2f15fda35b","type":"ha-sensor","z":"ad1d92815f2810e3","name":"Осадки сейчас","entityConfig":"e90834b91730474e","version":0,"state":"payload","stateType":"msg","attributes":[{"property":"update","value":"updated","valueType":"msg"}],"inputOverride":"allow","outputProperties":[],"x":940,"y":160,"wires":[[]]},{"id":"1b430bc67266fc46","type":"ha-sensor","z":"ad1d92815f2810e3","name":"Осадки на неделю","entityConfig":"079e8fb6221f5071","version":0,"state":"payload","stateType":"msg","attributes":[{"property":"update","value":"updated","valueType":"msg"}],"inputOverride":"allow","outputProperties":[],"x":950,"y":260,"wires":[[]]},{"id":"c8f660c6f44cbf00","type":"join","z":"ad1d92815f2810e3","name":"Объединение в строку","mode":"custom","build":"string","property":"payload","propertyType":"msg","key":"topic","joiner":"\\n","joinerType":"str","accumulate":false,"timeout":"","count":"1","reduceRight":false,"reduceExp":"","reduceInit":"","reduceInitType":"","reduceFixup":"","x":710,"y":260,"wires":[["1b430bc67266fc46"]]},{"id":"d5f87c9849faccbe","type":"join","z":"ad1d92815f2810e3","name":"Объединение в строку","mode":"custom","build":"string","property":"payload","propertyType":"msg","key":"topic","joiner":"\\n","joinerType":"str","accumulate":false,"timeout":"","count":"1","reduceRight":false,"reduceExp":"","reduceInit":"","reduceInitType":"num","reduceFixup":"","x":710,"y":160,"wires":[["0760bb2f15fda35b"]]},{"id":"faec5435d1fd53df","type":"sort","z":"ad1d92815f2810e3","name":"","order":"ascending","as_num":false,"target":"payload","targetType":"msg","msgKey":"payload","msgKeyType":"elem","seqKey":"payload","seqKeyType":"msg","x":570,"y":300,"wires":[["c8f660c6f44cbf00"]]},{"id":"e90834b91730474e","type":"ha-entity-config","server":"31f480d3.0e3b28","deviceConfig":"","name":"sensor config for Осадки сейчас","version":6,"entityType":"sensor","haConfig":[{"property":"name","value":"Осадки сейчас"},{"property":"device_class","value":""},{"property":"icon","value":"mdi:weather-pouring"},{"property":"unit_of_measurement","value":""},{"property":"state_class","value":""},{"property":"last_reset","value":""}],"resend":true},{"id":"079e8fb6221f5071","type":"ha-entity-config","server":"31f480d3.0e3b28","deviceConfig":"","name":"sensor config for Осадки на неделю","version":6,"entityType":"sensor","haConfig":[{"property":"name","value":"Осадки на неделю"},{"property":"device_class","value":""},{"property":"icon","value":"mdi:weather-pouring"},{"property":"unit_of_measurement","value":""},{"property":"state_class","value":""},{"property":"last_reset","value":""}],"resend":true},{"id":"31f480d3.0e3b28","type":"server","name":"Home Assistant","version":5,"addon":true,"rejectUnauthorizedCerts":true,"ha_boolean":"y|yes|true|on|home|open","connectionDelay":true,"cacheJson":true,"heartbeat":false,"heartbeatInterval":"30","areaSelector":"friendlyName","deviceSelector":"friendlyName","entitySelector":"friendlyName","statusSeparator":"at: ","statusYear":"hidden","statusMonth":"short","statusDay":"numeric","statusHourCycle":"h23","statusTimeFormat":"h:m","enableGlobalContextStore":true}]
Код для MSN
[{"id":"19cbf5e1e88f2024","type":"tab","label":"Зонт от MSN","disabled":false,"info":"","env":[]},{"id":"ab5ae602979d5186","type":"inject","z":"19cbf5e1e88f2024","name":"каждый 15 минут","props":[{"p":"payload"}],"repeat":"900","crontab":"","once":true,"onceDelay":"5","topic":"","payload":"","payloadType":"date","x":130,"y":80,"wires":[["7fb408618d93a612"]]},{"id":"7fb408618d93a612","type":"delay","z":"19cbf5e1e88f2024","name":"Случайная задержка","pauseType":"random","timeout":"30","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":360,"y":80,"wires":[["de2ef8c68437fb20"]]},{"id":"de2ef8c68437fb20","type":"http request","z":"19cbf5e1e88f2024","name":"Запрос осадков сейчас","method":"GET","ret":"txt","paytoqs":"ignore","url":"https://www.msn.com/ru-ru/weather/life/in-Москва,Россия","tls":"","persist":false,"proxy":"","insecureHTTPParser":false,"authType":"","senderr":false,"headers":[{"keyType":"other","keyValue":"user-agent","valueType":"other","valueValue":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36"}],"x":150,"y":180,"wires":[["cd3d04497b69e8b9","dafc373cb1e4ef54"]]},{"id":"cd3d04497b69e8b9","type":"html","z":"19cbf5e1e88f2024","name":"Выбираем характеристики","property":"payload","outproperty":"payload","tag":"div.lifeIndexBarTitle-E1_1","ret":"text","as":"single","x":460,"y":140,"wires":[["e2748d35141c91e0","30fda68a6944851f"]]},{"id":"dafc373cb1e4ef54","type":"html","z":"19cbf5e1e88f2024","name":"Выбираем значения характеристик","property":"payload","outproperty":"payload","tag":"div.lifeIndexBarSummary-E1_1","ret":"text","as":"single","x":490,"y":200,"wires":[["e2748d35141c91e0","30fda68a6944851f"]]},{"id":"30fda68a6944851f","type":"debug","z":"19cbf5e1e88f2024","name":"debug 1","active":true,"tosidebar":true,"console":true,"tostatus":true,"complete":"payload","targetType":"msg","statusVal":"payload","statusType":"auto","x":950,"y":300,"wires":[]},{"id":"e2748d35141c91e0","type":"merge","z":"19cbf5e1e88f2024","name":"","timeout":"2","x":730,"y":160,"wires":[["d03b49b3583b8fea"]]},{"id":"d03b49b3583b8fea","type":"function","z":"19cbf5e1e88f2024","name":"Объединение значений","func":"var array1 = msg.payload[0].payload;\nvar array2 = msg.payload[1].payload;\n\nvar newArray = \"\";\n for (var i = 0; i < array1.length && i < array2.length; i++) {\n newArray += array1[i] + \": \" + array2[i]+\"\\r\\n\";\n }\nmsg.payload = newArray;\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":930,"y":160,"wires":[["30fda68a6944851f","eca2fbc2f5eb3a41"]]},{"id":"eca2fbc2f5eb3a41","type":"ha-sensor","z":"19cbf5e1e88f2024","name":"Одежда по погоде","entityConfig":"628079d19b822784","version":0,"state":"payload","stateType":"msg","attributes":[],"inputOverride":"allow","outputProperties":[],"x":1050,"y":60,"wires":[[]]},{"id":"628079d19b822784","type":"ha-entity-config","server":"31f480d3.0e3b28","deviceConfig":"","name":"lifeBar","version":"6","entityType":"sensor","haConfig":[{"property":"name","value":"Одежда по погоде"},{"property":"icon","value":""},{"property":"entity_category","value":""},{"property":"entity_picture","value":""},{"property":"device_class","value":""},{"property":"unit_of_measurement","value":""},{"property":"state_class","value":""}],"resend":false,"debugEnabled":false},{"id":"31f480d3.0e3b28","type":"server","name":"Home Assistant","version":5,"addon":true,"rejectUnauthorizedCerts":true,"ha_boolean":"y|yes|true|on|home|open","connectionDelay":true,"cacheJson":true,"heartbeat":false,"heartbeatInterval":"30","areaSelector":"friendlyName","deviceSelector":"friendlyName","entitySelector":"friendlyName","statusSeparator":"at: ","statusYear":"hidden","statusMonth":"short","statusDay":"numeric","statusHourCycle":"h23","statusTimeFormat":"h:m","enableGlobalContextStore":true}]
У этого решения есть существенный недостаток — если дизайн сайта измениться, придется искать новый селектор.
ссылка на оригинал статьи https://habr.com/ru/post/724154/
Добавить комментарий