Luxeon UPS: различия между версиями
Sirmax (обсуждение | вклад) (→Скрипт) |
Sirmax (обсуждение | вклад) |
||
(не показаны 3 промежуточные версии этого же участника) | |||
Строка 377: | Строка 377: | ||
=Исправленный и дополненный скрипт и template для Zabbix= |
=Исправленный и дополненный скрипт и template для Zabbix= |
||
+ | ==Конфиг для агента== |
||
− | |||
+ | * не забыть или убрать логгирование или настроить логротейт |
||
* <code>UserParameter-voltage.conf</code> (часть <code>UserParameter=voltage[*] ... </code> не используется ) |
* <code>UserParameter-voltage.conf</code> (часть <code>UserParameter=voltage[*] ... </code> не используется ) |
||
<PRE> |
<PRE> |
||
UserParameter=voltage[*],/usr/bin/cat /etc/zabbix/scripts/voltages.json | /usr/bin/cat /etc/zabbix/scripts/voltages.json | /usr/bin/jq --arg jq_var $1 '.data | .[] | select(."{#VOLTMETER_NAME}" == $jq_var) | ."{#VOLTAGE}"' 2>&1 | tee -a /var/log/zabbix-agent-debug.log |
UserParameter=voltage[*],/usr/bin/cat /etc/zabbix/scripts/voltages.json | /usr/bin/cat /etc/zabbix/scripts/voltages.json | /usr/bin/jq --arg jq_var $1 '.data | .[] | select(."{#VOLTMETER_NAME}" == $jq_var) | ."{#VOLTAGE}"' 2>&1 | tee -a /var/log/zabbix-agent-debug.log |
||
UserParameter=voltage.discovery,/usr/bin/cat /etc/zabbix/scripts/voltages.json | tee -a /var/log/zabbix-agent-debug.log |
UserParameter=voltage.discovery,/usr/bin/cat /etc/zabbix/scripts/voltages.json | tee -a /var/log/zabbix-agent-debug.log |
||
+ | </PRE> |
||
+ | |||
+ | ==systemd unit== |
||
+ | <PRE>zabbix-agent-voltmeter.service</PRE> |
||
+ | <PRE> |
||
+ | [Unit] |
||
+ | Description=Zabbix Agent Voltmeter |
||
+ | After=syslog.target |
||
+ | After=network.target |
||
+ | |||
+ | [Service] |
||
+ | Type=simple |
||
+ | Restart=on-failure |
||
+ | ExecStart=/etc/zabbix/scripts/voltage_new.py |
||
+ | [Install] |
||
+ | WantedBy=multi-user.target |
||
</PRE> |
</PRE> |
||
Строка 680: | Строка 697: | ||
==Темплейт== |
==Темплейт== |
||
{{#spoiler:show=Temlate Luxeon Voltage v2| |
{{#spoiler:show=Temlate Luxeon Voltage v2| |
||
+ | |||
+ | <PRE> |
||
+ | <?xml version="1.0" encoding="UTF-8"?> |
||
+ | <zabbix_export> |
||
+ | <version>5.0</version> |
||
+ | <date>2024-08-01T08:00:13Z</date> |
||
+ | <groups> |
||
+ | <group> |
||
+ | <name>Power</name> |
||
+ | </group> |
||
+ | </groups> |
||
+ | <templates> |
||
+ | <template> |
||
+ | <template>Template Voltage Sensor</template> |
||
+ | <name>Template Voltage Sensor</name> |
||
+ | <groups> |
||
+ | <group> |
||
+ | <name>Power</name> |
||
+ | </group> |
||
+ | </groups> |
||
+ | <applications> |
||
+ | <application> |
||
+ | <name>Power</name> |
||
+ | </application> |
||
+ | </applications> |
||
+ | <items> |
||
+ | <item> |
||
+ | <name>Voltage discovery</name> |
||
+ | <key>voltage.discovery</key> |
||
+ | <delay>30s</delay> |
||
+ | <history>1h</history> |
||
+ | <trends>0</trends> |
||
+ | <value_type>TEXT</value_type> |
||
+ | <applications> |
||
+ | <application> |
||
+ | <name>Power</name> |
||
+ | </application> |
||
+ | </applications> |
||
+ | <preprocessing> |
||
+ | <step> |
||
+ | <type>JAVASCRIPT</type> |
||
+ | <params>var records = JSON.parse(value); |
||
+ | Zabbix.Log(1, "Item voltage.discovery") |
||
+ | Zabbix.Log(1, JSON.stringify(records)) |
||
+ | Zabbix.Log(1, "END of Item voltage.discovery") |
||
+ | return value</params> |
||
+ | </step> |
||
+ | </preprocessing> |
||
+ | </item> |
||
+ | </items> |
||
+ | <discovery_rules> |
||
+ | <discovery_rule> |
||
+ | <name>Voltemter Discovery</name> |
||
+ | <type>DEPENDENT</type> |
||
+ | <key>voltmeter.discovery.data</key> |
||
+ | <delay>0</delay> |
||
+ | <item_prototypes> |
||
+ | <item_prototype> |
||
+ | <name>Voltage [{#VOLTMETER_NAME}]</name> |
||
+ | <type>DEPENDENT</type> |
||
+ | <key>voltage.processed[{#VOLTMETER_NAME}]</key> |
||
+ | <delay>0</delay> |
||
+ | <history>1024d</history> |
||
+ | <trends>0</trends> |
||
+ | <value_type>FLOAT</value_type> |
||
+ | <units>V</units> |
||
+ | <applications> |
||
+ | <application> |
||
+ | <name>Power</name> |
||
+ | </application> |
||
+ | </applications> |
||
+ | <preprocessing> |
||
+ | <step> |
||
+ | <type>JSONPATH</type> |
||
+ | <params>$[?(@.VOLTMETER_NAME == "{#VOLTMETER_NAME}")].VOLTAGE_PROCESSED.first()</params> |
||
+ | </step> |
||
+ | </preprocessing> |
||
+ | <master_item> |
||
+ | <key>voltage.discovery</key> |
||
+ | </master_item> |
||
+ | </item_prototype> |
||
+ | <item_prototype> |
||
+ | <name>Voltage Raw Data [{#VOLTMETER_NAME}]</name> |
||
+ | <type>DEPENDENT</type> |
||
+ | <key>voltage.raw[{#VOLTMETER_NAME}]</key> |
||
+ | <delay>0</delay> |
||
+ | <history>1024d</history> |
||
+ | <trends>0</trends> |
||
+ | <value_type>FLOAT</value_type> |
||
+ | <units>V</units> |
||
+ | <description>Data as-is, without modification</description> |
||
+ | <applications> |
||
+ | <application> |
||
+ | <name>Power</name> |
||
+ | </application> |
||
+ | </applications> |
||
+ | <preprocessing> |
||
+ | <step> |
||
+ | <type>JSONPATH</type> |
||
+ | <params>$[?(@.VOLTMETER_NAME == "{#VOLTMETER_NAME}")].VOLTAGE.first()</params> |
||
+ | </step> |
||
+ | </preprocessing> |
||
+ | <master_item> |
||
+ | <key>voltage.discovery</key> |
||
+ | </master_item> |
||
+ | </item_prototype> |
||
+ | </item_prototypes> |
||
+ | <graph_prototypes> |
||
+ | <graph_prototype> |
||
+ | <name>Voltage</name> |
||
+ | <graph_items> |
||
+ | <graph_item> |
||
+ | <sortorder>1</sortorder> |
||
+ | <color>1A7C11</color> |
||
+ | <item> |
||
+ | <host>Template Voltage Sensor</host> |
||
+ | <key>voltage.processed[{#VOLTMETER_NAME}]</key> |
||
+ | </item> |
||
+ | </graph_item> |
||
+ | </graph_items> |
||
+ | </graph_prototype> |
||
+ | <graph_prototype> |
||
+ | <name>Voltage (raw data)</name> |
||
+ | <graph_items> |
||
+ | <graph_item> |
||
+ | <sortorder>1</sortorder> |
||
+ | <color>1A7C11</color> |
||
+ | <item> |
||
+ | <host>Template Voltage Sensor</host> |
||
+ | <key>voltage.raw[{#VOLTMETER_NAME}]</key> |
||
+ | </item> |
||
+ | </graph_item> |
||
+ | </graph_items> |
||
+ | </graph_prototype> |
||
+ | </graph_prototypes> |
||
+ | <master_item> |
||
+ | <key>voltage.discovery</key> |
||
+ | </master_item> |
||
+ | <lld_macro_paths> |
||
+ | <lld_macro_path> |
||
+ | <lld_macro>{#VOLTMETER_NAME}</lld_macro> |
||
+ | <path>$.VOLTMETER_NAME</path> |
||
+ | </lld_macro_path> |
||
+ | </lld_macro_paths> |
||
+ | <preprocessing> |
||
+ | <step> |
||
+ | <type>JAVASCRIPT</type> |
||
+ | <params>var records = JSON.parse(value); |
||
+ | Zabbix.Log(1, "Discovery Rule") |
||
+ | Zabbix.Log(1, JSON.stringify(records)) |
||
+ | Zabbix.Log(1, "END OF Discovery Rule") |
||
+ | return value</params> |
||
+ | </step> |
||
+ | </preprocessing> |
||
+ | </discovery_rule> |
||
+ | </discovery_rules> |
||
+ | <tags> |
||
+ | <tag> |
||
+ | <tag>Application</tag> |
||
+ | <value>Power</value> |
||
+ | </tag> |
||
+ | </tags> |
||
+ | </template> |
||
+ | </templates> |
||
+ | </zabbix_export> |
||
+ | |||
+ | </PRE> |
||
}} |
}} |
Текущая версия на 16:24, 13 августа 2024
Мониторинг напряжения на UPS Luxeon
Прежде чем начать
- В примере в схеме общий минус так как сама плата Raspberry питается от тех же батарей. Если это не так, и плата питается от 220 через блок питания, то нужно соединить "землю" платы и минус батарейного блока!
- К датчику напряжения подключается ОДИН провод, если подключить два все сгорит, не нужно так! Вторая точка, относительно которой производится измерение это земля и именно для этого соединяется земля платы и минус батарейной сборки
Постановка задачи
Есть UPS/инвертор (24В): Файл:Ep3000-pro (1).pdf
К нему подключены 2 батареи по 100 Ач, 12Вб последовательно. RS232 или не работает или использует протокол с которым я не смог разобраться.
Для прогнозирования времени работы единственный способ получить данные - это мониторинг напряжения на аккумуляторах.
Вся схема собрана "на коленке" за час, из тех деталей что были в наличии на макетной плате.
Аппаратная часть
Для мониторинга использую то что есть под рукой а именно
- Raspberry Pi Model 1 (самая старая, какая есть)
- Датчики INA-219 (2шт используются, еще 2 на случай подключения большего числа батарей)
INA-219 подключается по интерфейсу I²C (2 проводной интерфейс), питание на датчик подается с распберри
У распберри
- pin 02 - +5В на Vcc датчиков
- pin 06 - Земля на Gnd датчиков
- pin 03 - I2C SDA (данные) на SDA датчиков
- pin 05 - I2C SCL (синхронизация) на SCL датчиков
- Напряжение которое требуется измерять подключается на
+Vin
, измерение происходит относительно уровня земли - Датчики и RaspberryPi питаются от тех же 24В через DC-DC преобразователь с выходом USB (преобразователь подключен на клеммы батарей UPSa).
Всего на одну шину можно подключить 4 датчика, адрес на шине задается с помошью перемычек (2 перемычки, дают 4 возможных адреса)
Другими словами все датчики подключены к 4 пинам распберри, отдельные пины для каждого датчика не нужны
Программная часть
Требуется включение поддержки I2C со стороны линукса
Самый простой способ - использовать raspi-config
который пропишет все что надо в /etc/modules-load.d/modules.conf
или вручную загрузить нужные модули:
lsmod | grep i2c i2c_bcm2835 16384 0 i2c_dev 20480 0
После загрузки модулей можно просканировать шину на предмет устройств:
i2cdetect 1
Параметр 1
это номер шины I2C ( их может быть более чем одна, но в моем случае - одна, с номером 1, /dev/i2c-1
WARNING! This program can confuse your I2C bus, cause data loss and worse! I will probe file /dev/i2c-1. I will probe address range 0x03-0x77. Continue? [Y/n] y 0 1 2 3 4 5 6 7 8 9 a b c d e f 00: -- -- -- -- -- -- -- -- -- -- -- -- -- 10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 40: 40 41 -- -- 44 45 -- -- -- -- -- -- -- -- -- -- 50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 70: -- -- -- -- -- -- -- --
В этом примере видно что есть устройства на адресах 0x40
, 0x41
, 0x44
, 0x45
(У меня фактически включены 4 датчика, но 2 не используются)
Для снятия данных с датчика использую простой скрипт на Python
,
библиотека для работы с ina-219 может быть установлена командой pip3 install pi-ina219
#!/usr/bin/env python3 from ina219 import INA219 from ina219 import DeviceRangeError import time SHUNT_OHMS = 0.1 COUNT = 10 def read(): V = ina1.voltage() return V ina1 = INA219(SHUNT_OHMS,address=0x40) ina1.configure() if __name__ == "__main__": c = 0 voltage_summ = 0 while c < COUNT: try: current_voltage = read() if current_voltage < 18: raise ValueError("Voltage can't be < 18v"); voltage_summ = voltage_summ + current_voltage c = c + 1 time.sleep(0.01) except: time.sleep(0.2) pass print("{V1:.3f}".format(V1=voltage_summ/COUNT))
В этом скрипте
ina1 = INA219(SHUNT_OHMS,address=0x40)
- 0x40 это адрес датчика, для снятия данных с нескольких датчиков его можно вынести в параметры или сделать копию скрипта =)if current_voltage < 18: raise ValueError("Voltage can't be < 18v");
нужна для того что бы игнорировать значения ниже 18Вольт, так как иногда происходит ошибка измеренияCOUNT = 10
число измерений, результат берется как среднее значение
Интеграция с системой мониторинга Zabbix
Для того что бы избежать возможных проблем данные снимаются регулярно, раз в минуту используя cron
:
cat /etc/cron.d/voltage
(за одно не нужно давать sudo
пользователю zabbix)
* * * * * root /etc/zabbix/scripts/voltage_0x40.py > /etc/zabbix/scripts/voltage_24v * * * * * root /etc/zabbix/scripts/voltage_0x41.py > /etc/zabbix/scripts/voltage_12v
Данные по 2 точкам (12В и 24В) сохраняются в тестовые файлы, например /etc/zabbix/scripts/voltage_24v
Zabbix-agent
прочто читает эти файлы и отдает как значения ключей
cat /etc/zabbix/zabbix_agentd.conf.d/UserParameter-voltage.conf
UserParameter=ups.luxeon.voltage_24v_level,/usr/bin/cat /etc/zabbix/scripts/voltage_24v UserParameter=ups.luxeon.voltage_12v_level,/usr/bin/cat /etc/zabbix/scripts/voltage_12v
Проверить работу можно командой zabbix_get
zabbix_get -s 192.168.29.29 -k ups.luxeon.voltage_12v_level 13.698
-s 192.168.29.29
- адрес заббикс-агента, IP адрес RaspberryPi куда подключены датчики-k ups.luxeon.voltage_12v_level
имя ключа
Zabbix Template
Темплейт (очень упрощенный)
Исправленный и дополненный скрипт и template для Zabbix
Конфиг для агента
- не забыть или убрать логгирование или настроить логротейт
UserParameter-voltage.conf
(частьUserParameter=voltage[*] ...
не используется )
UserParameter=voltage[*],/usr/bin/cat /etc/zabbix/scripts/voltages.json | /usr/bin/cat /etc/zabbix/scripts/voltages.json | /usr/bin/jq --arg jq_var $1 '.data | .[] | select(."{#VOLTMETER_NAME}" == $jq_var) | ."{#VOLTAGE}"' 2>&1 | tee -a /var/log/zabbix-agent-debug.log UserParameter=voltage.discovery,/usr/bin/cat /etc/zabbix/scripts/voltages.json | tee -a /var/log/zabbix-agent-debug.log
systemd unit
zabbix-agent-voltmeter.service
[Unit] Description=Zabbix Agent Voltmeter After=syslog.target After=network.target [Service] Type=simple Restart=on-failure ExecStart=/etc/zabbix/scripts/voltage_new.py [Install] WantedBy=multi-user.target