Tasmota voltmeter (#1397)

* added millivolts to tasmota_ to get ANALOG/Range value

* allow to print_thresholds in tasmota plugin

* Experimented with different graph settings to obtain best axis labels

If voltage limits were eg 11 and 14 volts, the labels and limits
default terribly to 10 to 20, and if you fix limits, then labels read
"11, 11, 11, 12, 12, 12, 13, ...".  alt-y-grid and alt-autoscale seem
to improve this a lot

* get_value -> get_status to better reflect what it's doing

* millivolts() forgot to account for invalid value "U"

---------

Co-authored-by: Tim Connors <tconnors@rather.puzzling.org>
This commit is contained in:
Tim Connors 2023-11-16 05:02:19 +11:00 committed by GitHub
parent 15670c8e6d
commit f2080448e1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 91 additions and 64 deletions

View File

@ -16,9 +16,9 @@ ln -s /usr/share/munin/plugins/tasmota_ /etc/munin/plugins/tasmota_hostname_curr
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:
"DS18B20","SCD40", "PMS5003" or "millivolts" 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
@ -26,7 +26,7 @@ https://github.com/spacelama/ansible-initial-server-setup/tree/master/roles/moni
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.
PMS5003, millivolts flags.
=head1 AUTHOR
@ -47,7 +47,7 @@ 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() {
get_status() {
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
@ -63,6 +63,8 @@ get_value() {
DEVICE=$(basename "$0" | cut -d_ -f2)
FUNCTION=$(basename "$0" | cut -d_ -f3)
. "$MUNIN_LIBDIR/plugins/plugin.sh"
if [ "$1" = "autoconf" ]; then
if ! which curl > /dev/null 2>&1 ; then
echo "no (no curl)"
@ -97,161 +99,186 @@ if [ "$1" = "suggest" ]; then
echo "${device}_${i}"
done
done
nodeattr -n 'tasmota&&millivolts' | while read -r device ; do
for i in millivolts ; do
echo "${device}_${i}"
done
done
exit
fi
voltage() {
axis=Volts
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
echo "$axis.label Voltage"
else
get_value 8 ".StatusSNS.ENERGY.Voltage"
echo "Volts.value $res"
get_status 8 ".StatusSNS.ENERGY.Voltage"
echo "$axis.value $res"
fi
}
current() {
axis=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
echo "$axis.label Current"
else
get_value 8 ".StatusSNS.ENERGY.Current"
echo "Current.value $res"
get_status 8 ".StatusSNS.ENERGY.Current"
echo "$axis.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"
for axis in ApparentPower ReactivePower Power ; do
echo "$axis.label $axis"
echo "$axis.type GAUGE"
echo "$axis.min 0"
print_thresholds "$axis"
done
else
for i in Power ApparentPower ReactivePower ; do
get_value 8 ".StatusSNS.ENERGY.$i"
echo "$i.value $res"
for axis in ApparentPower ReactivePower Power ; do
get_status 8 ".StatusSNS.ENERGY.$axis"
echo "$axis.value $res"
done
fi
}
powerfactor() {
axis=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
echo "$axis.min 0"
echo "$axis.max 1"
echo "$axis.label Power Factor"
else
get_value 8 ".StatusSNS.ENERGY.Factor"
echo "PowerFactor.value $res"
get_status 8 ".StatusSNS.ENERGY.Factor"
echo "$axis.value $res"
fi
}
energy() {
axis=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
echo "$axis.label Energy"
echo "$axis.draw AREA"
else
get_value 8 ".StatusSNS.ENERGY.Total"
echo "Energy.value $res"
get_status 8 ".StatusSNS.ENERGY.Total"
echo "$axis.value $res"
fi
}
DS18B20() {
axis=Temperature
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
echo "$axis.label Temperature"
echo "$axis.type GAUGE"
#echo "$axis.min 0"
else
get_value 10 ".StatusSNS.DS18B20.Temperature"
echo "Temperature.value $res"
get_status 10 ".StatusSNS.DS18B20.Temperature"
echo "$axis.value $res"
fi
}
SCD40() {
axis=CO2
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
echo "$axis.label Carbon Dioxide"
echo "$axis.type GAUGE"
else
get_value 8 ".StatusSNS.SCD40.CarbonDioxide"
echo "CO2.value $res"
get_status 8 ".StatusSNS.SCD40.CarbonDioxide"
echo "$axis.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 )
axis=$( 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"
echo "$axis.label $lab"
echo "$axis.type GAUGE"
echo "$axis.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 )
axis=$( echo "$v" | cut -d= -f 1 )
field=$( echo "$v" | cut -d= -f 2 )
get_value 8 ".StatusSNS.PMS5003.$field"
echo "$i.value $res"
get_status 8 ".StatusSNS.PMS5003.$field"
echo "$axis.value $res"
done
fi
}
[ "$1" = "config" ] && echo "graph_category sensors"
millivolts() {
axis=Volts
if [ "$1" = "config" ]; then
limits=
# # man rrdgraph for relevant --limit args
# if [ -n "$lower" ] ; then
# limits="$limits --lower-limit $lower --rigid --allow-shrink"
# limits="$limits --lower-limit $lower --rigid --alt-autoscale"
# fi
# if [ -n "$upper" ] ; then
# limits="$limits --upper-limit $upper --rigid"
# fi
echo "graph_title Tasmota Volts: $DEVICE"
# echo "graph_args --base 1000$limits"
echo "graph_args --base 1000 --alt-autoscale --alt-y-grid"
echo "graph_vlabel Volts"
echo "$axis.label V"
echo "$axis.type GAUGE"
else
get_status 8 ".StatusSNS.ANALOG.Range"
if [ "$res" != U ] ; then
res=$( echo "$res" | awk '{printf "%0.3f", $1/1000}' )
fi
echo "$axis.value $res"
fi
}
case "$FUNCTION" in
voltage|power|powerfactor|current|energy|DS18B20|SCD40|PMS5003)
voltage|power|powerfactor|current|energy|DS18B20|SCD40|PMS5003|millivolts)
$FUNCTION "$1"
;;
*)
echo "Unknown Function"
;;
esac
if [ "$1" = "config" ] ; then
echo "graph_category sensors"
print_thresholds "$axis"
fi