Initial commit
This commit is contained in:
commit
2afa8027d8
6 changed files with 289 additions and 0 deletions
10
.digitemprc
Normal file
10
.digitemprc
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
TTY /dev/ttyUSB0
|
||||||
|
READ_TIME 1000
|
||||||
|
LOG_TYPE 1
|
||||||
|
LOG_FORMAT "%b %d %H:%M:%S Sensor %s C: %.2C F: %.2F"
|
||||||
|
CNT_FORMAT "%b %d %H:%M:%S Sensor %s #%n %C"
|
||||||
|
HUM_FORMAT "%b %d %H:%M:%S Sensor %s C: %.2C F: %.2F H: %h%%"
|
||||||
|
SENSORS 3
|
||||||
|
ROM 0 0x10 0x7E 0x66 0xD0 0x02 0x08 0x00 0xC5
|
||||||
|
ROM 1 0x28 0xFF 0xEB 0xF0 0x50 0x17 0x04 0x0B
|
||||||
|
ROM 2 0x28 0xFF 0xDB 0xD7 0x50 0x17 0x04 0x79
|
||||||
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
output
|
||||||
86
parseOutput
Executable file
86
parseOutput
Executable file
|
|
@ -0,0 +1,86 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
#
|
||||||
|
# Copyright (c) 2018 leopold@shdx.org
|
||||||
|
# Author: Der_Leopold
|
||||||
|
#
|
||||||
|
# This script simply parses the text file created by readSensor and
|
||||||
|
# prints the requested value. It is supposed to be called by the Zabbix
|
||||||
|
# agent.
|
||||||
|
# To prevent processing of stale data, it compares the timestamp from
|
||||||
|
# the file to the current one and returns an error if the difference is
|
||||||
|
# too big.
|
||||||
|
#
|
||||||
|
|
||||||
|
# Maximum data age in seconds. If the data is older, print an error and exit.
|
||||||
|
MAXAGE=300
|
||||||
|
|
||||||
|
# File to read the sensor data from
|
||||||
|
DATAFILE=/opt/1wire/output
|
||||||
|
|
||||||
|
function print_usage () {
|
||||||
|
echo ""
|
||||||
|
echo "Usage:"
|
||||||
|
echo ""
|
||||||
|
echo " parseOutput <LuftTemp|WasserTemp|BodenTemp>"
|
||||||
|
echo ""
|
||||||
|
}
|
||||||
|
|
||||||
|
function parse_datafile () {
|
||||||
|
# REGEX="^(\w+)=(\d+\.*\d*)$" # should work but does not?
|
||||||
|
REGEX="^(\w+)=(.*)$"
|
||||||
|
while read -r LINE; do
|
||||||
|
if [[ $LINE =~ $REGEX ]]; then
|
||||||
|
KEY=${BASH_REMATCH[1]}
|
||||||
|
VALUE=${BASH_REMATCH[2]}
|
||||||
|
case $KEY in
|
||||||
|
"Timestamp")
|
||||||
|
THRESHOLD=$(( $VALUE + $MAXAGE ))
|
||||||
|
TS=$(date +"%s")
|
||||||
|
if (( $TS <= $THRESHOLD )); then
|
||||||
|
TSVALID=1
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
"LuftTemp")
|
||||||
|
if [ $PARAM == "LuftTemp" ]; then
|
||||||
|
RESULT=$VALUE
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
"WasserTemp")
|
||||||
|
if [ $PARAM == "WasserTemp" ]; then
|
||||||
|
RESULT=$VALUE
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
"BodenTemp")
|
||||||
|
if [ $PARAM == "BodenTemp" ]; then
|
||||||
|
RESULT=$VALUE
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
done < "$DATAFILE"
|
||||||
|
}
|
||||||
|
|
||||||
|
PARAM="$1"
|
||||||
|
|
||||||
|
if [[ ( ! $# -eq 1 ) || ( $PARAM != "LuftTemp" && $PARAM != "WasserTemp" && $PARAM != "BodenTemp" ) ]]; then
|
||||||
|
print_usage
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! -r $DATAFILE ]; then
|
||||||
|
echo "Error: cannot read data file"
|
||||||
|
exit 1
|
||||||
|
else
|
||||||
|
TSVALID=0
|
||||||
|
parse_datafile
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ $TSVALID -eq 0 ]; then
|
||||||
|
echo "Error: Data file contains old or invalid data"
|
||||||
|
exit 1
|
||||||
|
else
|
||||||
|
echo "$RESULT"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
93
post2mqtt.py
Executable file
93
post2mqtt.py
Executable file
|
|
@ -0,0 +1,93 @@
|
||||||
|
#!/usr/bin/python
|
||||||
|
|
||||||
|
import sys, string, time, atexit
|
||||||
|
|
||||||
|
import paho.mqtt.client as mqtt
|
||||||
|
|
||||||
|
# ---- Configuration START ----
|
||||||
|
|
||||||
|
topic = 'neues-haus/keller/tele/werkstatt/'
|
||||||
|
mqttBroker = '192.168.0.11'
|
||||||
|
mqttPort = 1883
|
||||||
|
mqttuser = 'werkstatt-pi'
|
||||||
|
mqttpasswort = 'h#st0$HYWq1Z2*'
|
||||||
|
valuesFile = '/opt/1wire/output'
|
||||||
|
maxDataAge = 300 # [s]
|
||||||
|
minTemp = -10.0 # [°C], for simple sanity check
|
||||||
|
maxTemp = 35.0 # [°C], for simple sanity check
|
||||||
|
debug = True
|
||||||
|
|
||||||
|
# ---- Configuration END ----
|
||||||
|
|
||||||
|
# MQTT init
|
||||||
|
def on_connect(client, userdata, flags, rc, properties):
|
||||||
|
if rc != 0:
|
||||||
|
print("Connection to MQTT broker failed with rc = ", rc)
|
||||||
|
|
||||||
|
try:
|
||||||
|
client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, 'werkstatt-pi')
|
||||||
|
client.username_pw_set(mqttuser, mqttpasswort)
|
||||||
|
client.on_connect = on_connect
|
||||||
|
client.connect(mqttBroker, port=mqttPort)
|
||||||
|
client.loop_start()
|
||||||
|
except:
|
||||||
|
print('Connection to MQTT broker failed')
|
||||||
|
sys.exit()
|
||||||
|
|
||||||
|
# Function definitions
|
||||||
|
|
||||||
|
def exit_handler():
|
||||||
|
client.publish(topic + 'LWT', 'Offline', 0, True)
|
||||||
|
|
||||||
|
def getValues():
|
||||||
|
values = {}
|
||||||
|
with open(valuesFile,"r") as f:
|
||||||
|
for line in f:
|
||||||
|
if debug:
|
||||||
|
print('line = ' + line)
|
||||||
|
|
||||||
|
splitted = line.split('=')
|
||||||
|
if len(splitted) == 2:
|
||||||
|
values[splitted[0].strip()] = splitted[1].strip()
|
||||||
|
|
||||||
|
return values
|
||||||
|
|
||||||
|
def publishMetrics():
|
||||||
|
payload = '{ "timestamp": "' + values['Timestamp'] + '"'
|
||||||
|
for key in ['LuftTemp', 'WasserTemp', 'BodenTemp']:
|
||||||
|
if key in values and float(values[key]) >= minTemp and float(values[key]) <= maxTemp:
|
||||||
|
payload = payload + ', "' + key + '": "' + values[key] + '"'
|
||||||
|
|
||||||
|
if debug:
|
||||||
|
print(key + ' = ' + values[key] + ' °C')
|
||||||
|
|
||||||
|
payload = payload + ' }'
|
||||||
|
|
||||||
|
if debug:
|
||||||
|
print('payload = ' + payload)
|
||||||
|
|
||||||
|
client.publish(topic + 'SENSOR', payload)
|
||||||
|
|
||||||
|
|
||||||
|
# Main
|
||||||
|
|
||||||
|
client.publish(topic + 'LWT', 'Online', 0, True)
|
||||||
|
atexit.register(exit_handler)
|
||||||
|
|
||||||
|
while(1):
|
||||||
|
values = getValues()
|
||||||
|
|
||||||
|
if not 'Timestamp' in values:
|
||||||
|
continue
|
||||||
|
|
||||||
|
dataAge = int(time.time() - int(values['Timestamp']))
|
||||||
|
|
||||||
|
if debug:
|
||||||
|
print('Data age = ' + str(dataAge) + ' seconds')
|
||||||
|
|
||||||
|
if dataAge > maxDataAge:
|
||||||
|
continue
|
||||||
|
|
||||||
|
publishMetrics()
|
||||||
|
|
||||||
|
time.sleep(60)
|
||||||
89
readSensor
Executable file
89
readSensor
Executable file
|
|
@ -0,0 +1,89 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
#
|
||||||
|
# Copyright (c) 2018 leopold@shdx.org
|
||||||
|
# Author: Der_Leopold
|
||||||
|
#
|
||||||
|
# This script tries to read sensor values from a 1wire bus and writes the results
|
||||||
|
# and a timestamp to a file. It is intended to be executed periodically, for
|
||||||
|
# example via crontab.
|
||||||
|
#
|
||||||
|
|
||||||
|
# Retry up to n times if the reading fails
|
||||||
|
RETRY=3
|
||||||
|
|
||||||
|
# Number of seconds to wait between retries
|
||||||
|
DELAY=2
|
||||||
|
|
||||||
|
# Specify the temperature range where you expect the sensors will be operating
|
||||||
|
# This is simply used as a safeguard to detect implausible sensor readings
|
||||||
|
MINTEMP=-30
|
||||||
|
MAXTEMP=40
|
||||||
|
|
||||||
|
# Interface that is connected to the 1wire bus
|
||||||
|
USETTY=/dev/ttyUSB0
|
||||||
|
|
||||||
|
# Location of the digittemp config file with data about the sensors
|
||||||
|
DIGITEMPCONF="/opt/1wire/.digitemprc"
|
||||||
|
|
||||||
|
# Command to use for reading the sensors
|
||||||
|
CMD="sudo /usr/bin/digitemp_DS9097"
|
||||||
|
CMDOPTS=" -q -s $USETTY -c $DIGITEMPCONF"
|
||||||
|
|
||||||
|
# Define sensors that should be queried
|
||||||
|
# Format: [<Label>]=<Id>
|
||||||
|
declare -A SENSORS=( [0]=LuftTemp [1]=WasserTemp [2]=BodenTemp )
|
||||||
|
|
||||||
|
# Location where the readings should be stored
|
||||||
|
OUTFILE="output"
|
||||||
|
RESULT=""
|
||||||
|
|
||||||
|
#
|
||||||
|
# no configuration/changes should be necessary below this line
|
||||||
|
#
|
||||||
|
|
||||||
|
cd "$(dirname "$0")";
|
||||||
|
touch "$OUTFILE" 2> /dev/null
|
||||||
|
|
||||||
|
if [ ! -w $OUTFILE ]; then
|
||||||
|
echo "Error: output file '$OUTFILE' not writeable"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
function read_sensor () {
|
||||||
|
OUTPUT=`$CMD $CMDOPTS -t $SENSORID`
|
||||||
|
VALUE=`echo "$OUTPUT" | awk -F "C: " '{print $2}' | awk -F " F:" '{print $1}'`
|
||||||
|
CNT=$(($CNT+1))
|
||||||
|
}
|
||||||
|
|
||||||
|
function check_output () {
|
||||||
|
if [[ $OUTPUT =~ fail ]] || [[ $OUTPUT =~ owAcquire ]] || [ ${VALUE%.*} -lt $MINTEMP ] || [ ${VALUE%.*} -gt $MAXTEMP ]; then
|
||||||
|
if [ $CNT -le $RETRY ]; then
|
||||||
|
sleep $DELAY
|
||||||
|
read_sensor
|
||||||
|
check_output
|
||||||
|
else
|
||||||
|
RESULT="$RESULT${SENSORS[$SENSORID]}=Error\n"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
function store_result () {
|
||||||
|
RESULT="$RESULT${SENSORS[$SENSORID]}=${VALUE}\n"
|
||||||
|
}
|
||||||
|
|
||||||
|
function write_to_file () {
|
||||||
|
echo "Timestamp="`date +%s` > "$OUTFILE"
|
||||||
|
|
||||||
|
echo -e "$RESULT" >> "$OUTFILE"
|
||||||
|
}
|
||||||
|
|
||||||
|
for SENSORID in "${!SENSORS[@]}"
|
||||||
|
do
|
||||||
|
CNT=0
|
||||||
|
read_sensor
|
||||||
|
check_output
|
||||||
|
store_result
|
||||||
|
sleep $DELAY
|
||||||
|
done
|
||||||
|
write_to_file
|
||||||
10
test.py
Normal file
10
test.py
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
valuesFile = 'output'
|
||||||
|
values = {}
|
||||||
|
|
||||||
|
with open(valuesFile,"r") as f:
|
||||||
|
for line in f:
|
||||||
|
splitted = line.split('=')
|
||||||
|
if len(splitted) == 2:
|
||||||
|
values[splitted[0].strip()] = splitted[1].strip()
|
||||||
|
|
||||||
|
print(values)
|
||||||
Loading…
Add table
Add a link
Reference in a new issue