====== Dallas 1-wire Sensoren ======
Derzeit haben wir mehrere Möglichkeiten 1-Wire Sensoren auszulesen.
===== RaspberryPi =====
Den RaspberryPi kann man gut zum Einlesen der Sensoren verwenden.
[[hardware:controllers:raspberry_pi_erweiterung_klein|Raspberry Pi-Erweiterung_klein]]\\
[[hardware:controllers:raspberry_pi_erweiterung_mit_schaltausgaengen_rev.1|Raspberry Pi-Erweiterung_groß]]\\
[[http://www.raspiprojekt.de/anleitungen/schaltungen/9-1wire-mit-temperatursensor-ds18b20.html]]
Ohne VZ-Erweiterung muss unter Umständen zusätzlich das Script /etc/modules modifiziert werden:
# 1wire
w1-gpio pullup=1 ( nicht bei den Raspberry Pi-Erweiterungen)
w1-therm
Eine Übersicht über die Sensoren bekommt man mit ''ls /sys/bus/w1/devices/''.
Mit dem Befehl ''cat /sys/bus/w1/devices/*/w1_slave'' kann man dann die Sensoren abfragen.
In der Datenbank des Volkszähler müssen die einzelnen Kanäle angelegt werden. Die Kanalnummern müssen dann in das Script bzw. Config-File übernommen werden [[software/middleware/einrichtung]].
Um das ganze dann in die Volkszählerdatenbank zu bekommen, gibt es mehrere Möglichkeiten.
==== Einlesen mit vzlogger ====
Siehe 1wire an GPIO des BananaPi, Abschnitt [[howto:bananapi:1wire an GPIO4#vzlogger.conf]].
==== Einlesen mit perl-Script ====
„apt-get install libdevice-serialport-perl“
Das Script mit ''chmod ugo+x get1wire.pl'' ausführbar machen:
#!/usr/bin/perl
# welche werte sollen geholt werden?
my %Daten = ( # Name => [ Adresse onewire, uuid-Volkszaehler , Faktor ]
"WWKessel" => ["28-0000022c2dd7", "834c8be0-293c-11e3-8abd-911b2ff9df4c" , 0.001] , # in GradC
"WWVorlauf" => ["28-0000022bef46", "860f8b30-2940-11e3-92d2-b39a45aed701" , 0.001] , # in GradC
"HzRueckl" => ["28-0000022bfba8", "793354f0-2941-11e3-8965-b9f953ac51a9" , 0.001] , # in GradC
"HzVorl" => ["28-0000022bfbf2", "9482c580-2941-11e3-a953-0f05013168f3" , 0.001] , # in GradC
"Abgas" => ["28-0000022c0f2d", "be748340-2941-11e3-8286-edbdc7c926b3" , 0.001] , # in GradC
"HzKessel" => ["28-0000022c1388", "d96476a0-2941-11e3-81f9-27853072856e" , 0.001] , # in GradC
"WWRueckl" => ["28-0000022c2742", "3336aa50-2942-11e3-8a3c-61212ee448b1" , 0.001] , # in GradC
"HzRaum" => ["28-0000023cc9e7", "4e3a22c0-2942-11e3-af9b-1b95cbbaf179" , 0.001] , # in GradC
);
# ****************** Werte lesen
while (($name) = each(%Daten)){
$addr = $Daten{$name}[0] ;
$fak = $Daten{$name}[2] ;
# Abfragen
$sensor_temp = `cat /sys/bus/w1/devices/${addr}/w1_slave 2>&1`;
#print $sensor_temp ;
# checken
if ( !($sensor_temp =~ /\ YES/ ) ) {
delete $Daten{$name};
print "CRC == FALSE\n";
next; #wieder zu while hochspringen
}
if ( ($sensor_temp =~ /85000/ ) ) { # t=85000 ist der defaultwert ohne Wandlung
delete $Daten{$name};
print "t=85000\n";
next; #wieder zu while hochspringen
}
# decodieren
$sensor_temp =~ /t=(\-?\d+)/i; # ALT: geht nicht bei Minusgraden$sensor_temp =~ /t=(\d+)/i;
$val = (($1*$fak)-0);
if ($val == 0) {
delete $Daten{$name};
print "t=0\n";
next; #wieder zu while hochspringen
}
# Wert im Hash ablegen
$Daten{$name}[3] = $val ;
# plotten
print " --> $name = $val\n";
}
# ****************** Wert in die Datenbank schreiben
if (1) {
use LWP::UserAgent;
while (($name) = each(%Daten)){
$uuid = $Daten{$name}[1] ;
$val = $Daten{$name}[3] ;
print $uuid . " : " . $val . "\n";
my $server_endpoint = "http://rasp1/middleware.php/data/${uuid}.json?value=" . $val;
#print "serverget = " . $server_endpoint . "\n";
# set custom HTTP request header fields
my $req = HTTP::Request->new(POST => $server_endpoint);
$req->header('content-type' => 'application/json');
$req->header('x-auth-token' => 'kfksj48sdfj4jd9d');
# add POST data to HTTP request body
$req->content(" ");
my $ua = LWP::UserAgent->new;
my $resp = $ua->request($req);
if ($resp->is_success) {
my $message = $resp->decoded_content;
print "Received reply: $message\n";
} else {
print "HTTP GET error code: ", $resp->code, "\n";
print "HTTP GET error message: ", $resp->message, "\n";
}
}
}
Das Script sollte dann manuell ausgeführt werden. Wenn alles erfolgreich war, dann kann das Script auch vom Cron ausführen lassen:
Mit crontab -e können dann im Intervall die Daten ausgelesen werden und in der Datenbank gespeichert werden. Achtung: Leerzeile am Ende nicht vergessen. Das Script wird mit der folgenden Einstellung alle 1min ausgeführt.
# m h dom mon dow command
*/1 * * * * /root/bin/get1wire >/dev/null 2>&1
===== BananaPi =====
Ein HowTo für den BananaPi ist hier zu finden: [[howto:bananapi:1wire an GPIO4|1wire an GPIO4]]
===== log_onewire.sh =====
Dieses Bash Script fragt den 1-Wire Bus mit [[http://www.digitemp.com/software.shtml|Digitemp]] ab und loggt die Daten in die Middleware. Die Sensoren müssen dazu direkt am Rechner angeschlossen sein.
[[https://github.com/volkszaehler/volkszaehler.org/blob/master/misc/controller/1wire/log_onewire.sh]]
===== log_onewire_ecmd.sh =====
Diese Variante liest Sensoren aus, die an einen [[software:controller::ethersex]] kompatiblen Mikrocontroller angeschlossen sind, aus. Dazu wird ECMD genutzt. Das Skript sollte als Cron-Job auf dem Middleware-Server laufen.
[[https://github.com/volkszaehler/volkszaehler.org/blob/master/misc/controller/1wire/log_onewire_ecmd.sh]]
Mit einem aktuellen Ethersex und aktiviertem "Onewire naming support" kann man jetzt auch die Sensoren mit ihrem Namen abfragen. Dazu muss man mit dem entsprechenden ecmd "1w name set x 1234567890abcdef Sensor1" einer Sensor-ID einen Namen zuweisen. Mit "1w name save" wird das persistent im EEPROM gespeichert. Dann kann man immer mit
"1w get Sensor1" statt "1w get 1234567890abcdef" die Temperatur abfragen.
Das "x" bezeichnet die Stelle in der Sensoren-Tabelle. Defaultmäßig ist Platz für 10 Sensoren.
Muss man den Sensor mal austauschen, reicht eine neue Zuordnung Sensor-ID -> Name und man muss nichts an seinen Scripten ändern.
===== control6.src =====
Dieses [[software:controller::ethersex|ethersex]] Control6-Skript loggt direkt gegen eine volkszaehler.org Middleware. Es sind keine weiteren serverseitigen Skripts oder Cron-Jobs mehr notwendig.
Um Control6 nutzen zu können muss dieses erst noch aktiviert und konfiguriert werden,
Dazu aktiviert ihr
Ethersex -> General Setup -> control6 scripts (EXPERIMENTAL)
Ethersex -> Network -> DNS support -> DNS-Server IP address
Konfiguriert wird es unter
Ethersex -> Protocols -> httplog clientt (EXPERIMENTAL)
Service: "volkszaehler.org"
Path: "middleware.php/data/"
[-] Include unix timstamp
[ ] Include uuid
UUID: "12345678-9ABC-DEF0-1234-56789ABCDEF0"
Randomize UUID
--- Debugging Flags
[-] HTTPLOG
Zusätzlich muss in der Ethersex Datei "protocols/httplog/httplog.c" die Zeile 50 geändert werden.
"GET " CONF_HTTPLOG_PATH "?";
wird durch
"POST " CONF_HTTPLOG_PATH "";
ersetzt.
Dann ganz normal kompilieren. "Include unix timstamp" funktioniert **so nicht** für Volkszaehler, siehe unten.
Bitte 1-Wire ID und Middleware UUID einsetzen!
dnl Copyright (c) 2008 by Jochen Roessner
dnl Copyright (c) 2011 by Justin Otherguy
dnl This program is free software; you can redistribute it and/or modify
dnl it under the terms of the GNU General Public License version 2 or later
dnl as published by the Free Software Foundation.
dnl
dnl This program is distributed in the hope that it will be useful,
dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
dnl GNU General Public License for more details.
dnl
dnl You should have received a copy of the GNU General Public License
dnl along with this program; if not, write to the Free Software
dnl Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
dnl
dnl For more information on the GPL, please go to:
dnl http://www.gnu.org/copyleft/gpl.html
dnl
C6_HEADER(`/* This will be in control6.h */')
char temp_str[5];
dnl max length of value string: 4 (ex. -12.3)
CONTROL_START
THREAD(1wirelog)
dnl get temperature from 1wire bus, change the sensor id!
int16_t temp = ONEWIRE_GET(<1-wire id>);
itoa_fixedpoint(temp, 1, temp_str);
dnl log against the middleware, change the sensor uuid!
HTTPLOG(".json?value=%s", temp_str);
WAIT(300);
THREAD_END(1wirelog)
ON STARTUP DO THREAD_START(1wirelog) END
CONTROL_END
Für control6 ist bei aktiviertem "Onewire naming support" ebenfalls eine neuer Befehlt vorhanden.
Mit "ONEWIRE_GET_BY_NAME(Sensors1)" wird die Temperatur des ensprechenden Sensors geliefert.
Das hat den großen Vorteil dass man die Firmware nicht neue bauen muss wenn sich der Sensor ändert.
Achtung: wenn der Name (noch) nicht existiet wird als Wert "32767" bzw. nach der Umwandung 3276.7°C geliefert.
Beispiel mit aktiviertem Timestamp und Namensupport :
C6_HEADER(`/* This will be in control6.h */')
dnl
#include "protocols/httplog/httplog.h"
#include "services/clock/clock.h"
dnl
CONTROL_START
THREAD(onewire)
dnl wait 30s for ntp time is set
WAIT(30);
int16_t temp2 = ONEWIRE_GET_BY_NAME(Heizung);
dnl check if temperatur is valid
if (temp2 < 1300){
char temp2_str[5];
itoa_fixedpoint(temp2, 1, temp2_str);
HTTPLOG("12345678-abcd-efgh-9876-123456789012.json?ts=%lu000&value=%s", clock_get_time(), temp2_str);
}
dnl please acivate syslog or remove next 3 lines
else {
SYSLOG("Error: Sensor Heizung not found !")
}
dnl pause for 300s in summary
WAIT(270);
THREAD_END(onewire)
ON STARTUP DO THREAD_START(onewire) END;
CONTROL_END
===== ESPeasy =====
Es gibt auch noch weitere Möglichkeiten einen DS18B20 1-Wire Sensor auszulesen und die Messwerte an die Middleware zu übertragen, z.B.mit einem [[hardware:controllers:espeasy|NodeMCU]].