diff --git a/plugins/power/tasmota_ b/plugins/power/tasmota_ new file mode 100755 index 00000000..e6f7420e --- /dev/null +++ b/plugins/power/tasmota_ @@ -0,0 +1,257 @@ +#!/bin/sh + +: << =cut + +=head1 NAME + +tasmota_ - logs voltage, energy usage, power, power factor and current logged from tasmota power switches + +To install the plugin, copy or move the plugin to /usr/share/munin/plugins/ set +the chmod to 755 and create a symbolic link: +ln -s /usr/share/munin/plugins/tasmota_ /etc/munin/plugins/tasmota_hostname_voltage +ln -s /usr/share/munin/plugins/tasmota_ /etc/munin/plugins/tasmota_hostname_energy +ln -s /usr/share/munin/plugins/tasmota_ /etc/munin/plugins/tasmota_hostname_power +ln -s /usr/share/munin/plugins/tasmota_ /etc/munin/plugins/tasmota_hostname_powerfactor +ln -s /usr/share/munin/plugins/tasmota_ /etc/munin/plugins/tasmota_hostname_current + +Plugin also implements suggests, so if you have nodeattr installed and +/etc/genders populated with "tasmota" as well as "powermon", +"DS18B20","SCD40" or "PMS5003" flags for those tasmota devices that +implement energy or temperature monitoring, you can run an ansible +play like this to set up your links: +https://github.com/spacelama/ansible-initial-server-setup/tree/master/roles/monitoring/tasks + +=head1 APPLICABLE SYSTEMS + +Any host that can access tasmota systems and has "jq" installed. Can +auto suggest values if nodeattr genders (debian: apt install genders) +installed and configured with tasmota, powermon, DS18B20, SCD40, +PMS5003 flags. + +=head1 AUTHOR + +Tim Connors + +=head1 LICENSE + +GPLv2 or later + +=head1 MAGICK MARKERS + + #%# family=auto + #%# capabilities=autoconf + +=cut + +cached_curl=none +# runs curl on "Status $1", and parses through jq -c "$2", setting the value in "$res" +# Caches the curl results for when we're plotting multiple (power) values +# -- don't forget to make sure we're not being called in a subshell! +get_value() { + if [ "$cached_curl" = none ] ; then + # run curl, cache the result, and if there was an error, set value to "U" + if ! cached_curl=$( curl --max-time 5 -fsS --data-urlencode "cmnd=Status $1" "http://$DEVICE/cm" ) ; then + cached_curl='{}' + fi + fi + res=$( echo "$cached_curl" | jq -c "$2" ) + if [ "$res" = null ] ; then + res=U + fi +} + +DEVICE=$(basename "$0" | cut -d_ -f2) +FUNCTION=$(basename "$0" | cut -d_ -f3) + +if [ "$1" = "autoconf" ]; then + if ! which curl > /dev/null 2>&1 ; then + echo "no (no curl)" + exit 0 + fi + if ! which jq > /dev/null 2>&1 ; then + echo "no (no jq)" + exit 0 + fi + + echo yes && exit 0 +fi + +if [ "$1" = "suggest" ]; then + nodeattr -n 'tasmota&&powermon' | while read -r device ; do + for i in voltage power powerfactor current energy ; do + echo "${device}_${i}" + done + done + nodeattr -n 'tasmota&&DS18B20' | while read -r device ; do + for i in DS18B20 ; do + echo "${device}_${i}" + done + done + nodeattr -n 'tasmota&&SCD40' | while read -r device ; do + for i in SCD40 ; do + echo "${device}_${i}" + done + done + nodeattr -n 'tasmota&&PMS5003' | while read -r device ; do + for i in PMS5003 ; do + echo "${device}_${i}" + done + done + exit +fi + +voltage() { + if [ "$1" = "config" ]; then + + echo "graph_title Tasmota Voltage: $DEVICE" + echo "graph_vlabel Volts" + echo "graph_args --base 1000 -l 0" + + echo "Volts.label Voltage" + exit 0 + else + get_value 8 ".StatusSNS.ENERGY.Voltage" + echo "Volts.value $res" + fi +} + +current() { + if [ "$1" = "config" ]; then + + echo "graph_title Tasmota Current: $DEVICE" + echo "graph_vlabel Amps" + echo "graph_args --base 1000 -l 0" + + echo "Current.label Current" + exit 0 + else + get_value 8 ".StatusSNS.ENERGY.Current" + echo "Current.value $res" + fi +} + +power() { + if [ "$1" = "config" ]; then + + echo "graph_title Tasmota Power: $DEVICE" + echo "graph_vlabel Watts" + echo "graph_args --base 1000 -l 0" + + for i in Power ApparentPower ReactivePower ; do + echo "${i}.label $i" + echo "${i}.type GAUGE" + echo "${i}.min 0" + done + else + for i in Power ApparentPower ReactivePower ; do + get_value 8 ".StatusSNS.ENERGY.$i" + echo "$i.value $res" + done + fi +} + +powerfactor() { + if [ "$1" = "config" ]; then + + echo "graph_title Tasmota Power factor: $DEVICE" + echo "graph_vlabel Power Factor" + echo "graph_args --base 1000 -l 0" + + echo "PowerFactor.min 0" + echo "PowerFactor.max 1" + echo "PowerFactor.label Power Factor" + exit 0 + else + get_value 8 ".StatusSNS.ENERGY.Factor" + echo "PowerFactor.value $res" + fi +} + +energy() { + if [ "$1" = "config" ]; then + + echo "graph_title Tasmota Energy: $DEVICE" + echo "graph_args --base 1000" + + echo "graph_vlabel kWh" + echo "Energy.label Energy" + echo "Energy.draw AREA" + + exit 0 + else + get_value 8 ".StatusSNS.ENERGY.Total" + echo "Energy.value $res" + fi +} + +DS18B20() { + if [ "$1" = "config" ]; then + + echo "graph_title Tasmota Temperature: $DEVICE" + echo "graph_args --base 1000" + + echo "graph_vlabel °C" + echo "Temperature.label Temperature" + echo "Temperature.type GAUGE" + #echo "Temperature.min 0" + + exit 0 + else + get_value 10 ".StatusSNS.DS18B20.Temperature" + echo "Temperature.value $res" + fi +} + +SCD40() { + if [ "$1" = "config" ]; then + + echo "graph_title Tasmota Carbon Dioxide: $DEVICE" + echo "graph_args --base 1000" + + echo "graph_vlabel PPM" + echo "CO2.label Carbon Dioxide" + echo "CO2.type GAUGE" + + exit 0 + else + get_value 8 ".StatusSNS.SCD40.CarbonDioxide" + echo "CO2.value $res" + fi +} + +PMS5003() { + if [ "$1" = "config" ]; then + + echo "graph_title Tasmota Particulate Pollution: $DEVICE" + echo "graph_args --base 1000" + + for v in 'PB1=<1μm PPD' 'PB2_5=<2.5μm PPD' 'PB10=<10μm PPD' ; do + i=$( echo "$v" | cut -d= -f 1 ) + lab=$( echo "$v" | cut -d= -f 2 ) + + echo "${i}.label $lab" + echo "${i}.type GAUGE" + echo "${i}.min 0" + done + + exit 0 + else + for v in 'PB1="PB1"' 'PB2_5="PB2.5"' 'PB10="PB10"' ; do + i=$( echo "$v" | cut -d= -f 1 ) + field=$( echo "$v" | cut -d= -f 2 ) + get_value 8 ".StatusSNS.PMS5003.$field" + echo "$i.value $res" + done + fi +} + +[ "$1" = "config" ] && echo "graph_category sensors" + +case "$FUNCTION" in + voltage|power|powerfactor|current|energy|DS18B20|SCD40|PMS5003) + $FUNCTION "$1" + ;; + *) + echo "Unknown Function" + ;; +esac