Блог

Публикуем статус компьютера с ОС Linux в MQTT брокер

Понадобилось мне тут знать, для автоматизаций, работает ли кто-то за компьютером или нет, и пал мой выбор на MQTT, накидал небольшой скрипт, добавил его в крон, и успешно пользуюсь некоторое время уже. Может кому-нибудь пригодится. Скрипт не претендует на изящность, работает да и ладно.

Для того чтобы скрипт сработал необходимо поставить пакет mosquitto-clients

Собственно сам герой сей записи:

#!/bin/bash #mqtt_state.sh HOSTNAME=$(cat /etc/hostname) MQTT_USER=mqtt MQTT_PASS=mqtt MQTT_HOST=192.168.1.50 MQTT_TOPIC="computer/$/status" case "$1" in -S) STATUS="off" ;; *) PROC=$(ps -A | grep kwin_x11 | awk {'print $1'}) USER=$(cat /proc/$PROC/environ | tr "\0" "\n" | grep USER | awk -F "=" '') NAME=$(cat /etc/passwd | grep $USER | awk -F ":" '') DISP=$(cat /proc/$PROC/environ | tr "\0" "\n" | grep DISPLAY | awk -F "=" '') STATUS=$(DISPLAY=$DISP xset dpms && DISPLAY=$DISP xset q | grep 'Monitor is' | awk '{ print tolower($3)}') if [ "$STATUS" != "on" ]; then STATUS="off" fi ;; esac mosquitto_pub -u $MQTT_USER -P $MQTT_PASS -h $MQTT_HOST -i "$HOSTNAME" -t "$" -m "{\"user\":\"$NAME\",\"state\":\"$STATUS\"}"

  • HOSTNAME - имя хоста которое мы будем публиковать в брокер, можно заменить на простой текст

  • MQTT_USER - имя пользователя брокера

  • MQTT_PASS - пароль пользователя броекра

  • MQTT_HOST - адрес брокера

  • MQTT_TOPIC - топик куда публикуются данны

  • еcase оператор выбора, в слчае запуска скрипта с ключом -S, в брокер публикуется статус компьютера "off" используется при выключении. В любом другом случае исполняется то, что описано ниже.

  • PROC - номер процесса, данная запись справедлива для KDE, для GNOME и других, тут будет своё значение.

  • USER - получаем логин пользователя текущей сессии

  • NAME - Получаем имя пользователя

  • DISP - получаем номер экрана

  • STATUS - получаем статус экрана. Если статус экрана не равен "on", считаем что компьютер выключен и сообщаем статус "off", такой статус отправляется например при включении хранителя экрана.

Данные публикуем в брокер в формате JSON

Даём скрипту права на исполнение и добавляем в cron. Путь необходимо указать свой

chmod x /opt/mqtt_state/mqtt_state.sh

crontab -e

* * * * * /opt/mqtt_state/mqtt_state.sh

Юнит systemd

Создаём юнит который будет вызывать скрипт при запуске сисистемы и в случае выключения/перезагрузки

[Unit] Description=MQTT state update scriipt Before=poweroff.target reboot.target After=network.target [Service] ExecStart=/opt/mqtt_state/mqtt_state.sh ExecStop=/opt/mqtt_state/mqtt_state.sh -S RemainAfterExit=yes [Install] WantedBy=multi-user.target

Сохраняем его в ~/.config/systemd/user/mqtt_state.service

Добавляем его в автозагрузку и перезагружаем демон

systemctl --user enable mqtt_state

sudo systemctl daemon-reload

Проверяем

systemctl --user status mqtt_state

Вывод

● mqtt_state.service - MQTT state update scriipt Loaded: loaded (/home/werewolfe/.config/systemd/user/mqtt_state.service; enabled; vendor preset: enabled) Active: active (exited) since Wed 2020-12-09 01:11:51 05; 3min 43s ago Process: 174640 ExecStart=/opt/mqtt_state/mqtt_state.sh (code=exited, status=0/SUCCESS) Main PID: 174640 (code=exited, status=0/SUCCESS) дек 09 01:11:51 desktop systemd[2179]: Started MQTT state update scriipt.

Уффф, вроде всё....

Home Assistant

В Home Assistant создаём два сенсора

- platform: mqtt name: desktop_user state_topic: computer/desktop/status value_template: "{{ value_json.user }}" - platform: mqtt name: desktop_status state_topic: computer/desktop/status value_template: "{{ value_json.state }}"

Получившийся результат

Спасибо, что дочитали до конца! Пожалуйста оцените запись, это поможет мне писать лучше :)


Красава. Очень полезный сенсор.

Присоединюсь +1

А смысл? У меня пинг сенсор тоже самое показывает. А без сети и этот сенсор ничего не покажет.

Пинг сенсор видит включён экран или нет? Мне было важно это видеть, так как компьютер я практически никогда не выключаю и он всегда в сети. 
Помимо этого можно в MQTT любые данные о системе отправлять и обратно принимать с MQTT сервера, но это уже немного другая история. 


Вернуться назад
Вернуться назад