Skip to content

Instantly share code, notes, and snippets.

@kiwi-cam
Last active January 2, 2022 13:46
Show Gist options
  • Save kiwi-cam/f7914825fca122adf64b193385a5a6d9 to your computer and use it in GitHub Desktop.
Save kiwi-cam/f7914825fca122adf64b193385a5a6d9 to your computer and use it in GitHub Desktop.
A bash script to read BLE temperature sensors and push values to MQTT/File. Requires a "sensors" file (line 6) which is a CSV list with MACADDRESS,NAME,OUTPUTFILE.
#!/bin/bash
mqtt_topic="mi_temp"
mqtt_ip="localhost"
sensors_file="/usr/lib/mi_temp/sensors"
handler()
{
logger -p 6 --tag=mitemp "Closing HCI device"
echo -e "\nClosing HCI device"
sudo hciconfig hci0 down
exit 255
}
trap handler EXIT
cel=$'\xe2\x84\x83'
per="%"
red='\033[1;31m'
green='\033[1;32m'
yellow='\033[1;33m'
nc='\033[0m'
while getopts ":d" opt; do
case ${opt} in
d ) # process option d
echo "Running as Daemon, pless Ctrl-C to stop"
logger -p 3 --tag=mitemp "Running as Daemon"
daemon=true
;;
\? ) echo "Usage: cmd [-d]"
;;
esac
done
script_name="$(basename "$(test -L "$0" && readlink "$0" || echo "$0")")"
lock_file="/var/tmp/$script_name"
if [ -e "${lock_file}" ] && kill -0 "$(cat "${lock_file}")"; then
logger -p 1 --tag=mitemp "Already found to be running."
exit 99
fi
trap 'rm -f "${lock_file}"; exit' INT TERM EXIT
echo $$ > "${lock_file}"
echo "Opening and initializing HCI device"
logger -p 6 --tag=mitemp "Opening and initializing HCI device"
sudo hciconfig hci0 up
echo "Enabling LE Mode"
sudo btmgmt le on
firstrun=true
while [ "$firstrun" = true ] || [ "$daemon" = true ] ; do
firstrun=false
while read -r item; do
sensor=(${item//,/ })
mac="${sensor[0]}"
name="${sensor[1]}"
outputFile="${sensor[2]}"
echo -e "\n${yellow}Sensor: $name ($mac)${nc}"
unset data
counter="0"
until [ -n "$data" ] || [ "$counter" -ge 5 ] ; do
counter=$((counter+1))
echo -n " Getting $name Temperature and Humidity... "
logger -p 6 --tag=mitemp "Getting ${name} Temperature and Humidity"
data=$(timeout 20 /usr/bin/gatttool -b "$mac" --char-write-req --handle=0x0038 -n 0100 --listen 2>&1 | grep -m 1 "Notification handle")
if [ -z "$data" ]; then
logger -p 2 --tag=mitemp "Failed getting ${name} Temperature and Humidity, waiting 5 seconds before trying again"
echo -e "${red}failed, waiting 2 seconds before trying again${nc}"
sleep 2
else
echo -e "${green}success${nc}"
fi
done
if [ "$counter" -ge 5 ]; then
echo -e "${red}Failed${nc}"
else
temphexa=$(echo $data | awk -F ' ' '{print $7$6}'| tr [:lower:] [:upper:] )
#Check for negatives
if [[ 0x$temphexa > 0xF000 ]]; then
temp=$(printf "%d\n" $((16#$temphexa - 16#FFFF)))
else
temp=$(( 16#$temphexa ))
fi
temp=$(echo "scale=2;$temp/100" | bc)
if [[ "$temp" =~ ^(\.[0-9]+)?$ ]]; then
temp="0${temp}"
fi
if [[ "$temp" =~ ^-(\.[0-9]+)?$ ]]; then
temp="-0${temp}"
fi
humhexa=$(echo $data | awk -F ' ' '{print $8}'| tr [:lower:] [:upper:])
humid=$(echo "ibase=16; $humhexa" | bc)
dewp=$(echo "scale=1; (243.12 * (l( $humid / 100) +17.62* $temp/(243.12 + $temp)) / 17.62 - (l( $humid / 100) +17.62* $temp/(243.12 + $temp)) )" | bc -l)
battery=$(echo $data | awk -F ' ' '{print $10$9}'| tr [:lower:] [:upper:] )
batteryV=$(echo "ibase=16; $battery" | bc)
batteryV=$(echo "scale=2;$batteryV/1000" | bc)
batt=$(echo "($batteryV-2.1)*100" | bc)
if (( $(echo "$batt > 100" | bc -l) )); then batt=100; fi
echo -e "${yellow} Temperature: $temp$cel${nc}"
echo -e "${yellow} Temperature HEX: $temphexa${nc}"
echo -e "${yellow} Humidity: $humid$per${nc}"
echo -e "${yellow} Battery Voltage: $batteryV V${nc}"
echo -e "${yellow} Battery Level: $batt$per${nc}"
echo -e "${yellow} Dew Point: $dewp$cel${nc}"
logger -p 6 --tag=mitemp "Temperature: $temp$cel ($temphexa), Humidity: $humid$per, Voltage: $batteryV V"
if [ -n "$outputFile" ]; then
logger -p 6 --tag=mitemp "Publishing data to $outputFile."
echo -e -n " Publishing data to $outputFile... "
if grep -q "time:" $outputFile; then
sed -i "/time/s/:.*/:$(date)/" "$outputFile"
else
echo "time:$(date)" >> "$outputFile"
fi
if [[ "$temp" =~ ^-{0,1}[0-9]+(\.[0-9]+)?$ ]]; then
if grep -q "temperature:" $outputFile; then
sed -i "/temperature/s/:.*/:$temp/" "$outputFile"
else
echo "temperature:$temp" >> "$outputFile"
fi
fi
if [[ "$humid" =~ ^[0-9]+(\.[0-9]+)?$ ]]; then
if grep -q "humidity:" $outputFile; then
sed -i "/humidity/s/:.*/:$humid/" "$outputFile"
else
echo "humidity:$humid" >> "$outputFile"
fi
fi
if [[ "$batt" =~ ^[0-9]+(\.[0-9]+)?$ ]]; then
if grep -q "battery:" $outputFile; then
sed -i "/battery/s/:.*/:$batt/" "$outputFile"
else
echo "battery:$batt" >> "$outputFile"
fi
fi
if [[ "$dewp" =~ ^[0-9]+(\.[0-9]+)?$ ]]; then
if grep -q "dewpt:" $outputFile; then
sed -i "/dewpt/s/:.*/:$dewp/" "$outputFile"
else
echo "dewpt:$dewp" >> "$outputFile"
fi
fi
echo -e "${green}done${nc}"
fi
if [ -n "$mqtt_topic" ]; then
logger -p 6 --tag=mitemp "Publishing data via MQTT"
echo -e -n " Publishing data via MQTT... "
mqttJSON="{\"Time\":\"${date}\",\"mi_temp.sh\": {"
if [[ "$temp" =~ ^-{0,1}[0-9]+(\.[0-9]+)?$ ]]; then
mqttJSON="${mqttJSON} \"Temperature\": $temp,"
fi
if [[ "$humid" =~ ^[0-9]+(\.[0-9]+)?$ ]]; then
mqttJSON="${mqttJSON} \"Humidity\": $humid,"
fi
if [[ "$batt" =~ ^[0-9]+(\.[0-9]+)?$ ]]; then
mqttJSON="${mqttJSON} \"Battery\": $batt,"
fi
if [[ "$dewp" =~ ^[0-9]+(\.[0-9]+)?$ ]]; then
mqttJSON="${mqttJSON} \"Dewpoint\": $dewp,"
fi
mqttJSON="${mqttJSON:0:-1}},\"TempUnit\":\"C\"}"
echo "Publishing MQTT to /$mqtt_topic/$name with JSON: ${mqttJSON}"
/usr/bin/mosquitto_pub --quiet -h $mqtt_ip -V mqttv311 -t "/$mqtt_topic/$name" -m "$mqttJSON"
echo -e "${green}done${nc}"
fi
fi
done < "$sensors_file"
done
echo -e "\nclosing HCI device"
sudo hciconfig hci0 down
echo "Finished"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment