#!/bin/bash # -*- sh -*- : << =cut =head1 NAME switchbotmeter_multi - Munin plugin to monitor temperature and humidity with SwitchBot Meter =head1 CONFIGURATION Obtain a token, secret and deviceid for SwitchBot API. See the following website. https://github.com/OpenWonderLabs/SwitchBotAPI =head1 ENVIRONMENT VARIABLES env.token : Token to access SwitchBot API. (Required) env.secret : Secret to access SwitchBot API. (Required) env.deviceid : Device ID(s) of SwitchBot Meter separated by white space. (Required) env.interval : Interval in seconds for API access. (Optional, default is 0) =head1 NOTES The amount of SwitchBot API calls per day is limited to 10000 times. If munin-node executes this plugin every 5 minutes, the API will be called 288 times a day. You can use env.interval parameter to prevent frequent API access. For example, if you set env.interval 900, the API response will be cached to local file for 900 seconds(15 minutes). =head1 AUTHOR K.Cima https://github.com/shakemid =head1 LICENSE GPLv2 SPDX-License-Identifier: GPL-2.0-only =head1 Magic markers #%# family=contrib #%# capabilities= =cut . "${MUNIN_LIBDIR}/plugins/plugin.sh" set -o nounset set -o pipefail # Token to access SwitchBot API token=${token:?} # Secret to access SwitchBot API secret=${secret:?} # Device ID of SwitchBot Meter deviceids=${deviceid:?} # Interval for API access (second) interval=${interval:-0} # Plugin Name pluginname=$( basename "$0" ) config() { local deviceid cat < "${MUNIN_STATEFILE}_${deviceid}" } fetch_api() { local deviceid temperature humidity battery t sign nonce http_response http_status api_response api_status deviceid=$1 t=$( date +'%s%3N' ) nonce=$( openssl rand -base64 32 ) sign=$( echo -n "${token}${t}${nonce}" | openssl dgst -sha256 -hmac "${secret}" -binary | openssl base64 ) http_response=$( curl -s --fail --retry 3 \ -w '\n%{http_code}\n' \ -H "Content-Type:application/json;charset=utf8" \ -H "Authorization:${token}" -H "t:${t}" -H "nonce:${nonce}" -H "sign:${sign}" \ "https://api.switch-bot.com/v1.1/devices/${deviceid}/status" ) http_status=$( echo "${http_response}" | tail -n 1 ) if [ "${http_status}" != "200" ]; then echo Error with HTTP status = "${http_status}" 1>&2 return 1 fi api_response=$( echo "${http_response}" | sed '$d' ) api_status=$( echo "${api_response}" | jq '.statusCode' ) if [ "${api_status}" != "100" ]; then echo Error with API status = "${api_status}" 1>&2 return 1 fi temperature=$( echo "${api_response}" | jq '.body.temperature' ) humidity=$( echo "${api_response}" | jq '.body.humidity' ) battery=$( echo "${api_response}" | jq '.body.battery' ) echo "temperature_${deviceid}=${temperature}" "humidity_${deviceid}=${humidity}" "battery_${deviceid}=${battery}" } # Main case ${1:-} in config) config if [ "${MUNIN_CAP_DIRTYCONFIG:-}" = "1" ]; then fetch fi ;; *) fetch ;; esac exit 0