Публикуем температуру, использование процессора, памяти и диска в MQTT для Home Assistant
Все точно работает на Raspbian Stretch, актуальной на момент данной публикации.
Так же все работает и на последней версии Raspbian Jessie
Есть очень удобная утилита awk, способная вытягивать только нужную нам информацию из выдаваемых данных. Именно ее будем использовать в скриптах.
Итак, у меня есть Hassio на отдельной малине, там же установлен брокер mosquitto.
Допустим, адрес hassio с брокером mosquitto 192.168.1.101
Так же у меня есть еще одна raspberry, с установленной xeoma, и я хочу получать информацию о ее состоянии в Home Assistant.
Я буду получать информацию о температуре процессора, загруженности процессора, использования оперативной памяти и жесткого диска (в данном случае корня флешки — / ), а так же процент использования usb диска и аптайм системы
Для начала установим необходимые пакеты python3:
sudo apt-get install python3-pip sudo apt-get install python3-setuptools sudo pip3 install paho-mqtt
Теперь установим mosquitto:
wget http://repo.mosquitto.org/debian/mosquitto-repo.gpg.key sudo apt-key add mosquitto-repo.gpg.key cd /etc/apt/sources.list.d/ sudo wget http://repo.mosquitto.org/debian/mosquitto-stretch.list
cd $home sudo apt-get update sudo apt-get install mosquitto sudo apt-get install mosquitto-clients rm mosquitto-repo.gpg.key
Теперь нужно создать скрипты.
Создадим папку mqtt в домашней директории raspberry:
sudo mkdir mqtt
и зайдем в нее:
cd mqtt
Пояснения по скриптам:
hostname=»192.168.1.101» это адрес брокера
«/rpi/temp» это топик
check_output([«vcgencmd«,»measure_temp«]) это команда для отображения
Первый скрипт температуры:
sudo nano temp.py
Содержимое:
#!/usr/bin/env python3 import paho.mqtt.publish as publish from subprocess import check_output from re import findall def get_temp(): temp = check_output(["vcgencmd","measure_temp"]).decode("UTF-8") return(findall("\d+\.\d+",temp)[0]) def publish_message(topic, message): print("Publishing to MQTT topic: " + topic) print("Message: " + message) publish.single(topic, message, hostname="192.168.1.101") temp = get_temp() publish_message("/rpi/temp", temp)
Скрипт загрузки процессора:
sudo nano cpu.py
#!/usr/bin/env python3 import paho.mqtt.publish as publish from subprocess import check_output from re import findall def get_data(): data = check_output(["sudo","bash","/home/pi/mqtt/cpu.sh"]).decode("UTF-8") return(findall("\d+",data)[0]) def publish_message(topic, message): print("Publishing to MQTT topic: " + topic) print("Message: " + message) publish.single(topic, message, hostname="192.168.1.101") data = get_data() publish_message("/rpi/cpu", data)
и для него же bash скрипт с командой:
sudo nano cpu.sh
Содержимое:
#!/bin/bash (grep 'cpu ' /proc/stat;sleep 0.1;grep 'cpu ' /proc/stat)|awk -v RS="" '{print ($13-$2+$15-$4)*100/($13-$2+$15-$4+$16-$5)}'
Скрипт загрузки оперативной памяти:
sudo nano ram.py
Содержимое:
#!/usr/bin/env python3 import paho.mqtt.publish as publish from subprocess import check_output from re import findall def get_data(): data = check_output(["sudo","bash","/home/pi/mqtt/ram.sh"]).decode("UTF-8") return(findall("\d+",data)[0]) def publish_message(topic, message): print("Publishing to MQTT topic: " + topic) print("Message: " + message) publish.single(topic, message, hostname="192.168.1.101") data = get_data() publish_message("/rpi/ram", data)
bash скрипт с командой:
sudo nano ram.sh
Содержимое:
#!/bin/bash awk '/MemTotal/{t=$2}/MemAvailable/{a=$2}END{print 100-100*a/t}' /proc/meminfo
—
Скрипт занятого места hdd:
sudo nano hdd.py
Содержимое:
#!/usr/bin/env python3 import paho.mqtt.publish as publish from subprocess import check_output from re import findall def get_data(): data = check_output(["sudo","bash","/home/pi/mqtt/hdd.sh"]).decode("UTF-8") return(findall("\d+",data)[0]) def publish_message(topic, message): print("Publishing to MQTT topic: " + topic) print("Message: " + message) publish.single(topic, message, hostname="192.168.1.101") data = get_data() publish_message("/rpi/hdd", data)
bash скрипт с командой:
sudo nano hdd.sh
Содержимое:
#!/bin/bash df | awk '/ \/$/{print $5}'
Скрипт занятого места usbhdd1:
sudo nano usbhdd1.py
Содержимое:
#!/usr/bin/env python3 import paho.mqtt.publish as publish from subprocess import check_output from re import findall def get_data(): data = check_output(["sudo","bash","/home/pi/mqtt/usbhdd1.sh"]).decode("UTF-8") return(findall("\d+",data)[0]) def publish_message(topic, message): print("Publishing to MQTT topic: " + topic) print("Message: " + message) publish.single(topic, message, hostname="192.168.1.101") data = get_data() publish_message("/rpi/usbhdd1", data)
bash скрипт:
#!/bin/bash df | awk '/hdd/ {print($5)}'
в скрипте стоит /hdd/ — это ориентир для поиска утилитой awk, у меня usb диск смонтирован в mnt/hdd, поэтому по hdd выполняется поиск и выводит колонку №5 в вывод
Скрипт аптайма:
sudo nano uptime.py
Содержимое:
#!/usr/bin/env python3 import paho.mqtt.publish as publish from subprocess import check_output from re import findall def get_data(): data = check_output(["sudo","bash","/home/pi/mqtt/uptime.sh"]).decode("UTF-8") return(data) def publish_message(topic, message): print("Publishing to MQTT topic: " + topic) print("Message: " + message) publish.single(topic, message, hostname="192.168.1.101") data = get_data() publish_message("/rpi/uptime", data)
bash:
#!/bin/bash #echo $(uptime) | sed 's/^.\+up\ \+\([^,]*\).*/\1/g' awk '{print $1/60}' /proc/uptime
Даем права на выполнение всех этих скриптов:
sudo chmod +x temp.py cpu.py cpu.sh ram.py ram.sh hdd.py hdd.sh uptime.py uptime.sh usbhdd1.py usbhdd1.sh
И теперь нужно проверить их выполнение, выполнив по очереди каждый:
sudo python3 temp.py
и так далее
Должно выйти сообщение:
Теперь настроим автоматическое выполнение всех этих скриптов через cron
sudo crontab -e
и добавляем в самом конце:
# mqtt publish: * * * * * /home/pi/mqtt/cpu.py; /home/pi/mqtt/hdd.py; /home/pi/mqtt/temp.py; /home/pi/mqtt/ram.py; /home/pi/mqtt/usbhdd1.py * * * * * sleep 30; /home/pi/mqtt/cpu.py; /home/pi/mqtt/hdd.py; /home/pi/mqtt/temp.py; /home/pi/mqtt/ram.py; /home/pi/mqtt/usbhdd1.py * * * * * /home/pi/mqtt/uptime.py
Теперь каждые 30 секунд будут выполняться все скрипты по очереди, аптайм раз в минуту
Чтобы добавить в Home Assistant, в sensors.yaml:
#################################################### # Статус системы Xeoma # #################################################### # Аптайм rasberry Xeoma в минутах - platform: mqtt name: "xeoma_rpi_uptime" state_topic: "/rpi/uptime" # Аптайм rasberry Xeoma кастом - platform: template sensors: kodi_rpi_bedroom_uptime_custom: icon_template: mdi:clock value_template: > {% set uptime = states.sensor.xeoma_rpi_uptime.state | int %} {% set minutes = (( uptime % 60) / 1) | int %} {% set hours = ((uptime % 1440) / 60) | int %} {% set days = (uptime / 1440) | int %} {% if uptime < 1 %} Меньше минуты {% else %} {% if days > 0 %} {{ days }} д. {% endif %} {% if hours > 0 %} {% if days > 0 %} {{ ' ' }} {% endif %} {{ hours }} ч. {% endif %} {% if minutes > 0 %} {% if days > 0 or hours > 0 %} {{ ' ' }} {% endif %} {{ minutes }} мин. {% endif %} {% endif %} # Температура rasberry Xeoma - platform: mqtt name: "xeoma_rpi_temp" state_topic: "/rpi/temp" unit_of_measurement: "°C" device_class: temperature # hdd системы rasberry Xeoma - platform: mqtt name: "xeoma_rpi_hdd" state_topic: "/rpi/hdd" unit_of_measurement: "%" # usbhdd1 Xeoma - platform: mqtt name: "xeoma_rpi_usbhdd1" state_topic: "/rpi/usbhdd1" unit_of_measurement: "%" # cpu rasberry Xeoma - platform: mqtt name: "xeoma_rpi_cpu" state_topic: "/rpi/cpu" unit_of_measurement: "%" # ram rasberry Xeoma - platform: mqtt name: "xeoma_rpi_ram" state_topic: "/rpi/ram" unit_of_measurement: "%"
Настраиваем имена, иконки и группы, и в итоге получается вот так:
UPD 30.05.19
Обновил bash скрипт аптайма и сенсоры аптайма в Home Assistant, теперь аптайм выглядит так:
Спасибо за замечательную статью!
100 лет искал что-либо подобное.
К сожалению не совсем понял куда вы инсталлировали пакеты питоновские.
На малинке с хассио или на хеома ?
Сам долго искал, поэтому собрал все в статью) пакеты ставятся на ту малинку, откуда шлются данные ( в моем случае это ксеома). А ассистент только принимает их через брокера. Ещё есть другие варианты публикации таких данных, но никак не доберусь затестить их)
Теперь все стало более-менее понятно. Надо пробовать! ))
Думаю взять пустую малинку, навесить на нее raspbian — так сказать для экспериментов.
Все верно, лучше экспериментировать не на рабочей малине) у меня это давно пройденный этап)
У меня крутятся 2 малины: main и rezerv, которая следит за мэйном и в случае ухода его с горизонта берет власть в свои руки по управлению HA.
На них я точно не буду экспериментировать )
Все замечательно ставится, никакой ругани, но, черт подери, информация не выуживается.
Статус датчиков — неизвестно.
Сам MQTT работает, по нему собираю статистику с розеток (энергопотребление).
Малинка на которой москито : 192.168.1.97
Но как раз параметры этой же малины пытаюсь прочитать.
А что за awk утилита такая ? Ее нужно ставить отдельно ? В скриптах я не обнаружил ссылок на нее. Ну или смотрел через одно место )
Если запустить скрипт вручную, данные через mqtt отправляются?
Выдает и виснет, после этого не могу в ssh что-либо делать. Причем одинаковая картина на 2-х малинках. Хорошо, что на них не HA крутятся. Хуже всего, что через какое-то время они дружно виснут уже капитально. Приходится обесточивать.
Я так понимаю в активе там только cron крутится ?
Как его можно остановить и убедиться, что малинки перестали виснуть ? До того, как навернул на них все по инструкции работали с месяц безупречно. На одном фильмы смотрел через коди, на другом круглосуточно в хроме выводится состояние HA. Ни разу зависаний не было.
Для начала уберите задания из крона, и уже после вручную искать причину. Самый простой скрипт на температуру, с него начните вручную запускать проверять. Права доступа, из под какого пользователя все это дело запускается, правильность установки питоновских приложений, все проверьте
Подскажите пожалуйста как задание из крона убрать ? Можно ли из графического интерфейса или только в командной строке ?
Я все в консоли делаю, sudo crontab -e и очищаете все задания что добавили ранее. Сохраняете
Спасибо! Сейчас попробую и понаблюдаю.
Из задания все очистил — обе малины перестали виснуть.
Пакеты все в порядке. Ставятся без алертов и ошибок.
Запустил все сценарии вручную, работают и читают информацию.
И да, работают если я нахожусь в директории mqtt. Вероятно по логике так и должно быть.
вручную работают, то есть по mqtt данные приходят?
если я в командной строке набираю «sudo python3 temp.py» и получаю значение скажем 53 это ведь не по mqtt или mqtt ?
Вам нужно проверить в скрипте топики, если у вас они не появляются в ассистенте. Если вручную скрипт отработал, то данные куда-то ушли и по mqtt. Как вариант поставьте на телефон, например, MQTT Dashboard (https://play.google.com/store/apps/details?id=com.thn.iotmqttdashboard&hl=ru) и подпишитесь на своего брокера. Если у вас уже что-то по mqtt ходит в ассистента, вы там все эти показания увидите, и так же при ручном выполнении скрипта вы так же увидите условное 53 при выполнении sudo python3 temp.py. Прога хороша для таких случаев как ваш, например, когда непонятно идут данные брокеру или нет
Большое спасибо! Непременно проверю.
Сделал все нуля на новой карточке.
Все заработало. Сенсоры HA показывают информацию.
Смущает некая неправдоподобность информации.
К примеру температура проца отличается от температуры, получаемой по команде «vcgencmd measure_temp» на пару градусов.
Uptime показывает 21 день 2 часа ))
У вас все корректно отображает ?
Отлично! Рад за вас) по поводу температуры, вы можете подставить свою команду для отображения и передачи , изучите внимательно скрипты. Таким способом можно вообще любой вывод передавать. Аптайм кстати у меня по другому работает, передает общее количество минут, а ассистент переводит в дни, часы и минуты. Нужно дополнить статью. Работает отлично, уже 89 дней намотал)
По аптайму очень верно говорите! Нужно тупо получать минуты. так надежнее ))
Большущее вам спасибо за ваши труды и ваш очень интересный ресурс!
Спасибо! Я обновил статью, изменил скрипт аптайма и сенсор в HA
Добиться таки нормальной работы мне удалось с выделенным на малинке сервером MQTT. Не жалею, так как в будущем на mqtt много чего будет передаваться. Зато сейчас все работает как часы )
Кстати, единственное слабое место — аптайм. После вставки вашего кастомного сенсора аптайма, проверка конфигуратора рисует пространственную ошибку строк на 10 )
В итоге сенсор не ставил, а просто применил ваш новый баш файл.
Термимо конечно, но как-то несмотрибельно, типа : 725.036
С кастомным сенсором может пробелы в началах строк не правильно расположены, будет время, прикреплю скрин, сравните с моим sensors.yaml
Да, скорее всего именно в этом проблема.
Нет, проблема не в пробелах. Есть датчик : # uptime raspberry 95 — platform: mqtt name: «95_mqtt_rpi_uptime» state_topic: «95_mqtt/rpi/uptime» И второй датчик с расчетом расчет : # Время в онлайне в днях — platform: template sensors: online_custom_95_day: value_template: > {% set uptime = states.sensor.95_mqtt_rpi_uptime.state | int %} {% set minutes = (( uptime % 60) / 1) | int %} {% set hours = ((uptime % 1440) / 60) | int %} итд… Так вот если вместо датчика для расчетов «95_mqtt_rpi_uptime» вставить другой существующий датчик к примеру «online» все работает. При вставке «95_mqtt_rpi_uptime» -ругается неимоверно. При этом сам датчик «sensor.95_mqtt_rpi_uptime»… Подробнее »
действительно странно. Может я не правильно понял, но в вашей ошибке есть строка «end of statement block’, got ‘_mqtt_rpi_uptime’) for dictionary value» Там стоит «_mqtt_rpi_uptime», а 95 перед этим нет. Может ассистенту не нравится наличие числа в начале имени? Попробуйте переименовать «95_mqtt_rpi_uptime» например в «mqtt_rpi_95_uptime», по типу названия второго (кастомного) датчика и после все это добавить в шаблон… Это так, мысли вслух
Думаю очень логичное объяснение.
Однако я решил не мудрствовать и применил ваш старый формат.
Он изначально показывает какую-то хрень, а потом, через пару часов стабилизируется и получается : 2 д., 12 ч., 07 м. , что, собственно, меня весьма и весьма устраивает.
В общем сейчас все чудесно. Спасибо вам! ))
Старый формат иногда неверно показывает) Поэтому я от него отказался, уж очень часто он действительно ерунду показывает
Ок, понял, пристально наблюдаю за ним.
Не понимаю, зачем вокруг всего этого наворачивать python, когда все эти монструозные скрипты можно уложить в одну строчку на шелле?
Вот простой пример — это сразу можно закидывать в крон.
mosquitto_pub -h host -u user -P password -t topic -m «$(vcgencmd measure_temp | sed ‘s/^[^0-9]*//;s/[^0-9\.]*$//’)»