From 2afa8027d82378cda7132c7cfd6ee37bf1c0ca79 Mon Sep 17 00:00:00 2001 From: Leopold Date: Sun, 15 Mar 2026 10:05:07 +0100 Subject: [PATCH] Initial commit --- .digitemprc | 10 ++++++ .gitignore | 1 + parseOutput | 86 ++++++++++++++++++++++++++++++++++++++++++++++++ post2mqtt.py | 93 ++++++++++++++++++++++++++++++++++++++++++++++++++++ readSensor | 89 +++++++++++++++++++++++++++++++++++++++++++++++++ test.py | 10 ++++++ 6 files changed, 289 insertions(+) create mode 100644 .digitemprc create mode 100644 .gitignore create mode 100755 parseOutput create mode 100755 post2mqtt.py create mode 100755 readSensor create mode 100644 test.py diff --git a/.digitemprc b/.digitemprc new file mode 100644 index 0000000..de289af --- /dev/null +++ b/.digitemprc @@ -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 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..53752db --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +output diff --git a/parseOutput b/parseOutput new file mode 100755 index 0000000..6969888 --- /dev/null +++ b/parseOutput @@ -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 " + 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 + diff --git a/post2mqtt.py b/post2mqtt.py new file mode 100755 index 0000000..6cb7ad0 --- /dev/null +++ b/post2mqtt.py @@ -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) diff --git a/readSensor b/readSensor new file mode 100755 index 0000000..f90a37e --- /dev/null +++ b/readSensor @@ -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: [