Публикуем температуру, использование процессора, памяти и диска в 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, теперь аптайм выглядит так:

0 0 vote
Article Rating

Подписаться
Уведомление о
guest

Этот сайт использует Akismet для борьбы со спамом. Узнайте как обрабатываются ваши данные комментариев.

30 Комментарий
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Sem2000
Sem2000
1 год назад

Спасибо за замечательную статью!
100 лет искал что-либо подобное.
К сожалению не совсем понял куда вы инсталлировали пакеты питоновские.
На малинке с хассио или на хеома ?

Sem2000
Sem2000
1 год назад
Reply to  kvv

Теперь все стало более-менее понятно. Надо пробовать! ))
Думаю взять пустую малинку, навесить на нее raspbian — так сказать для экспериментов.

Sem2000
Sem2000
1 год назад
Reply to  kvv

У меня крутятся 2 малины: main и rezerv, которая следит за мэйном и в случае ухода его с горизонта берет власть в свои руки по управлению HA.
На них я точно не буду экспериментировать )

Sem2000
Sem2000
1 год назад
Reply to  Sem2000

Все замечательно ставится, никакой ругани, но, черт подери, информация не выуживается.
Статус датчиков — неизвестно.
Сам MQTT работает, по нему собираю статистику с розеток (энергопотребление).
Малинка на которой москито : 192.168.1.97
Но как раз параметры этой же малины пытаюсь прочитать.
А что за awk утилита такая ? Ее нужно ставить отдельно ? В скриптах я не обнаружил ссылок на нее. Ну или смотрел через одно место )

Sem2000
Sem2000
1 год назад
Reply to  kvv

Выдает и виснет, после этого не могу в ssh что-либо делать. Причем одинаковая картина на 2-х малинках. Хорошо, что на них не HA крутятся. Хуже всего, что через какое-то время они дружно виснут уже капитально. Приходится обесточивать.
Я так понимаю в активе там только cron крутится ?
Как его можно остановить и убедиться, что малинки перестали виснуть ? До того, как навернул на них все по инструкции работали с месяц безупречно. На одном фильмы смотрел через коди, на другом круглосуточно в хроме выводится состояние HA. Ни разу зависаний не было.

Sem2000
Sem2000
1 год назад
Reply to  kvv

Подскажите пожалуйста как задание из крона убрать ? Можно ли из графического интерфейса или только в командной строке ?

Sem2000
Sem2000
1 год назад
Reply to  kvv

Спасибо! Сейчас попробую и понаблюдаю.

Sem2000
Sem2000
1 год назад
Reply to  Sem2000

Из задания все очистил — обе малины перестали виснуть.
Пакеты все в порядке. Ставятся без алертов и ошибок.
Запустил все сценарии вручную, работают и читают информацию.
И да, работают если я нахожусь в директории mqtt. Вероятно по логике так и должно быть.

Sem2000
Sem2000
1 год назад
Reply to  kvv

если я в командной строке набираю «sudo python3 temp.py» и получаю значение скажем 53 это ведь не по mqtt или mqtt ?

Sem2000
Sem2000
1 год назад
Reply to  kvv

Большое спасибо! Непременно проверю.

Sem2000
Sem2000
1 год назад
Reply to  Sem2000

Сделал все нуля на новой карточке.
Все заработало. Сенсоры HA показывают информацию.
Смущает некая неправдоподобность информации.
К примеру температура проца отличается от температуры, получаемой по команде «vcgencmd measure_temp» на пару градусов.
Uptime показывает 21 день 2 часа ))
У вас все корректно отображает ?

Sem2000
Sem2000
1 год назад
Reply to  kvv

По аптайму очень верно говорите! Нужно тупо получать минуты. так надежнее ))
Большущее вам спасибо за ваши труды и ваш очень интересный ресурс!

Sem2000
Sem2000
1 год назад
Reply to  kvv

Добиться таки нормальной работы мне удалось с выделенным на малинке сервером MQTT. Не жалею, так как в будущем на mqtt много чего будет передаваться. Зато сейчас все работает как часы )
Кстати, единственное слабое место — аптайм. После вставки вашего кастомного сенсора аптайма, проверка конфигуратора рисует пространственную ошибку строк на 10 )
В итоге сенсор не ставил, а просто применил ваш новый баш файл.
Термимо конечно, но как-то несмотрибельно, типа : 725.036

Sem2000
Sem2000
1 год назад
Reply to  kvv

Да, скорее всего именно в этом проблема.

Sem2000
Sem2000
1 год назад
Reply to  Sem2000

Нет, проблема не в пробелах. Есть датчик : # 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»… Подробнее »

Sem2000
Sem2000
1 год назад
Reply to  kvv

Думаю очень логичное объяснение.
Однако я решил не мудрствовать и применил ваш старый формат.
Он изначально показывает какую-то хрень, а потом, через пару часов стабилизируется и получается : 2 д., 12 ч., 07 м. , что, собственно, меня весьма и весьма устраивает.
В общем сейчас все чудесно. Спасибо вам! ))

Sem2000
Sem2000
1 год назад
Reply to  kvv

Ок, понял, пристально наблюдаю за ним.

Евгений
1 месяц назад

Не понимаю, зачем вокруг всего этого наворачивать python, когда все эти монструозные скрипты можно уложить в одну строчку на шелле?

Вот простой пример — это сразу можно закидывать в крон.

mosquitto_pub -h host -u user -P password -t topic -m «$(vcgencmd measure_temp | sed ‘s/^[^0-9]*//;s/[^0-9\.]*$//’)»