ZigBee на Raspberry, часть 2, установка софта

Итак, в первой части мы прошили стикер CC2531, теперь наша малинка готова стать шлюзом. Обычно схема работы Raspberry следующая:

ZigBee2MQTT — нужен для того чтобы принять пакеты со стика CC2531 и отправить их в брокер сообщений. Которые в дальнейшем уже обработают скрипты для автоматизации чего-либо.

Сначала поставим брокер сообщений mosquitto (как самое легкое):

sudo apt-get install mosquitto

И настроим файл конфигурации /etc/mosquitto/mosquitto.conf :

pid_file /run/mosquitto/mosquitto.pid
persistence true
persistence_location /var/lib/mosquitto/
log_dest file /var/log/mosquitto/mosquitto.log
include_dir /etc/mosquitto/conf.d
allow_anonymous true   # доступ для всех
listener 1883 0.0.0.0  # слушаем все сетевые адреса

Можно задать логин пароль для доступа, и разрешить слушать только localhost, но я это считаю излишним, т.к. всё равно чаще всего raspberry pi лежит в локальной сети и в интернет не смотрит. Далее включаем службу и стартуем её:

sudo systemctl enable mosquitto
sudo systemctl restart mosquitto

Теперь ставим и настраиваем ZigBee2MQTT. Можно по туториалу на сайте разработчиков, а можно так, как описано ниже (без подробностей).

sudo apt-get install nodejs git
corepack enable
sudo mkdir /opt/zigbee2mqtt
sudo chown -R ${USER}: /opt/zigbee2mqtt
git clone --depth 1 https://github.com/Koenkk/zigbee2mqtt.git /opt/zigbee2mqtt
cd /opt/zigbee2mqtt
pnpm install --frozen-lockfile
cd /opt/zigbee2mqtt
pnpm start

После успешного старта будет доступен веб интерфейс для дальнейшей настройки в браузере http://ip:8080.

Необходимо зайти, выбрать порт где расположен стик, и ввести данные для подключения к брокеру. После сохранить. Конфиг будет сохранен в /opt/zigbee2mqtt/data/configuration.yaml

Далее оформим запуск ZigBee2MQTT как службу, создав и сохранив файл:

[Unit]
Description=zigbee2mqtt
After=network.target

[Service]
Environment=NODE_ENV=production
Type=notify
ExecStart=/usr/bin/node index.js
WorkingDirectory=/opt/zigbee2mqtt
StandardOutput=inherit
# Or use StandardOutput=null if you don't want Zigbee2MQTT messages filling syslog, for more options see systemd.exec(5)
StandardError=inherit
WatchdogSec=10s
Restart=always
RestartSec=10s
User=pi

[Install]
WantedBy=multi-user.target
sudo systemctl enable zigbee2mqtt
sudo systemctl start zigbee2mqtt

Ну и теоретически всё. По идее можно подключать устройства zigbee. В следующей части собственно это и рассмотрю.

Update: в итоге решил таки не хранить все яйца в одном месте, и брокер сообщений mosquitto перенес с raspberry на другое устройство. В этом случае нужно установить пароль и чуть перенастроить конфигурационный файл

Установка пароля:

sudo mosquitto_passwd -c /etc/mosquitto/passwd логин
chown mosquitto /etc/mosquitto/passwd
chmod 0700 /etc/mosquitto/passwd

И конфиг в конечном итоге у меня выглядит так:

pid_file /run/mosquitto/mosquitto.pid
persistence true
persistence_location /var/lib/mosquitto/
log_dest file /var/log/mosquitto/mosquitto.log
include_dir /etc/mosquitto/conf.d
allow_anonymous false   # доступ для всех
password_file /etc/mosquitto/passwd
listener 1883 0.0.0.0 

ZigBee на Raspberry, часть 1, прошивка CC2531

Задача: научится принимать пакеты по протоколу Zigbee на устройстве Raspberry PI 3. Сама по себе, без внешних дополнительных устройств, Raspberry этого не умеет. Нужен модем, который может принимать сигналы на этой частоте. Для этого было куплено на Aliexpress устройство Zigbee CC2531. Покупателю оно приходит пустое, без прошивки, поэтому перед работой с ним, его необходимо прошить. Есть несколько вариантов, самый простой сделать это при помощи самой же RaspberryPI. Одно Но! (и даже их несколько):

  • нужно делать самому подключение проводками
  • на модеме ножки очень тонкие, и стандартные проводки от Arduino например не подойдут. Я городил огород при помощи малярного скотча, а кто-то отгибал ножки и припаивался к ним на прямую.

Общая схема подключения для прошивки следующая:

После того как наколхозите этот переходник, можно начинать прошивку. Но сначала убедимся, что модем вообще виден в системе, выполнив команду lsusb. Должно выйти что-то вроде:

Если всё ок, двигаемся к следующему шагу: скачиваем утилиту для прошивки:

git clone https://github.com/jmichault/flash_cc2531.git
cd flash_cc2531
./cc_chipid

И скорее всего получим фигу вида:

root@raspberrypi:/home/donpadlo/flash_cc2531# ./cc_chipid
bash: ./cc_chipid: cannot execute: required file not found

Я подозреваю, что этой утилите не хватает библиотеки wiringPi. Установить её можно так:

git clone https://github.com/WiringPi/WiringPi.git
cd WiringPi
 ./build

И далее снова попробовать выполнить :

./cc_chipid

И я снова получил туже самую ошибку. Ну чтож..попробуем собрать банарник из исходных годов сами:

cd flash_cc2531
make

После чего, команда уже выполнится корректно:

./cc_read
ID = b534

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

wget https://github.com/Koenkk/Z-Stack-firmware/raw/refs/heads/master/coordinator/Z-Stack_3.0.x/bin/CC2531_20190425.zip
unzip CC2531_20190425.zip
./cc_erase 
./cc_write CC2531ZNP-with-SBL.hex

И собственно всё. Теперь стик рабочий. Осталось научится получать с него данные. А это уже в следующих частях..

OpenVPN клиент на RaspberryPi

В наличии: файл ovpn. Задача установить соединение.

Решении: напишем скрипт и положим в крон:

# Сей дивный скрипт устанавливает VPN содениение с сервером грибовы.рф и если оное установлено, то включает светодиодик..
result=$(ifconfig | grep tun0)
echo $result
if [[ "$result" == *"tun0"* ]]; then
  echo "-ok";
  /root/scripts/gpio/led2_on.py
else
  echo "-fail";
  /usr/sbin/openvpn /root/vpn/malgino.ovpn
fi

Подсчет количества открытий страницы в минуту

Задача: вывести счетчик посещений определенной web страницы в минуту.

Решение: простой способ «в лоб» — парсить логи apache

#!/bin/bash
cat /var/log/httpd/access_log | grep $(date --date '-1 min' '+%R') | grep invoice -c >/var/www/html/cnt.txt

Пакетное сжатие файлов JPG

Задача: сжать файлы формата JPG во всех встречающихся папках.

Решение: воспользуемся утилитой jpegoptim совместно с find:

find . -name "*.jpg" | xargs jpegoptim -f -m 70

1 2 3 59