1wire

Från Basvrak
Hoppa till navigering Hoppa till sök

Länkar till otestat mög

[redigera]

http://www.digitemp.com/

En annan variant (läs "hack") på lösning baserat på OWW

[redigera]

Översikt

[redigera]

Basmög: "one-wire weather", http://oww.sourceforge.net/

OWW kan läsa flera temperatursensorer men loggar i grundutförande enbart en. Därför får man göra en patch för att logga mer data. Loggningen sker via http till ett CGI-script. Webservern kan därefter göra behandling av data.

En bättre lösning är troligtvis att skriva något som använder owfs (one-wire filesystem) på sensorsidan och om man kör mätningarna på samma burk som loggningen dessutom ersätta webserverskickandet med ett rent cronjobb.

Färdighårdvara från temperatur.nu, med usb-adapter (ex https://shop.temperatur.nu/temperaturnat-1-sensor-p-30.html). Möget körs på en linuxmaskin med 2.6.16-kärna.

Jag har valt att använda RRD för loggning eftersom den kan rita fina grafer, göra vissa uträkningar, etc. För att kunna använda detta behöver man skapa en rrd-fil först:

rrdtool create weather.rrd DS:temp:GAUGE:600:U:U RRA:AVERAGE:0.5:1:576 RRA:MIN:0.5:1:576 RRA:MAX:0.5:1:576 RRA:AVERAGE:0.5:6:432 RRA:MIN:0.5:6:432 RRA:MAX:0.5:6:432 RRA:AVERAGE:0.5:24:540 RRA:MIN:0.5:24:540 RRA:MAX:0.5:24:540 RRA:AVERAGE:0.5:288:450 RRA:MIN:0.5:288:450 RRA:MAX:0.5:288:450

Parametrarna är gott magiska och jag minns inte vad de betyder.

Skapa en per sensor, i scripten nedan finns det en "weather_indoor.rrd" också.

Konfigurering

[redigera]

Sätt konfigureringen i OWW att använda dallasprotokollet:

httpdallas http://<adress till server och katalog med mög i>/weather.php
httpdallason 1

Konfigurera även ID för sensorerna så att de inte byter plats logiskt om de byter plats fysiskt.

Loggningsscript

[redigera]

weather.php

Uppdaterar en rrd-fil samt loggar temperaturen i en textfil för att undvika att något tappas bort när rrd slår runt. Använder två parametrar "Tem" och "Tem2" som skickas av oww (se patchen nedan)

<?php

        $filetostorein = "temperatures.log";
        $filetostoreindoor = "temperatures_indoor.log";

# get the temperature from the request

        $temp = $_REQUEST['Tem'];
        $indoor = $_REQUEST['Tem2'];

# get the date (seconds since 1970)

        $t = time();

        $handle = fopen($filetostorein,"a");
        fwrite($handle, $t . " " . $temp . "\n");
        fclose($handle);

        $handle = fopen($filetostoreindoor,"a");
        fwrite($handle, $t . " " . $indoor . "\n");
        fclose($handle);


# update rrd database

        system("/opt/csw/bin/rrdupdate weather.rrd $t:$temp");
        system("/opt/csw/bin/rrdupdate weather_indoor.rrd $t:$indoor");
?>

Script för presentation av data

[redigera]

Jag använder tre script som är väldigt lika, graph.php, weekgraph.php, monthgraph.php.

graph.php

<?php
        header('Content-Type: image/png');
        system("./baz.sh");

        print file_get_contents("weather.png");
?>

Skillnaden ligger i att de anropar olika shellscript, baz.sh, wbaz.sh, mbaz.sh.

JA, det går att göra snyggare och optimalare, men man skall inte ändra saker som fungerar...

baz.sh

#!/usr/bin/bash

/opt/csw/bin/rrdtool graph weather.png  -z -f "" -t "Temperature - Last day"  -E  -a PNG \
DEF:tmax=weather.rrd:temp:MAX DEF:indoor=weather_indoor.rrd:temp:AVERAGE \
DEF:tmin=weather.rrd:temp:MIN DEF:temp=weather.rrd:temp:AVERAGE \
DEF:yday=weather.rrd:temp:AVERAGE:end=now-1d:start=end-1d \
SHIFT:yday:86400 VDEF:tempmax=tmax,MAXIMUM VDEF:tempmin=tmin,MINIMUM \
CDEF:diff=temp,yday,- \
LINE1:diff#ffff00:"" \
LINE1:indoor#0000FF:"" LINE1:temp#FF0000:"" \
 LINE1:yday#00FF00:"" \
GPRINT:tempmin:"Min %2.1lf C" LINE0.5:tempmax#6699FF:"" LINE0.5:tempmin#6699FF GPRINT:tempmax:"Max %2.1lf C" \
VDEF:tempavg=temp,AVERAGE GPRINT:tempavg:"Avg %2.1lf C" VDEF:tempcur=temp,LAST GPRINT:tempcur:"Now %2.1lf C" \
GPRINT:tempcur:"Time %H.%M\n":strftime \
VDEF:inavg=indoor,AVERAGE VDEF:inmax=indoor,MAXIMUM VDEF:inmin=indoor,MINIMUM VDEF:incur=indoor,LAST \
GPRINT:inmin:"Inmin %2.1lf C" GPRINT:inmax:"Inmax %2.1lf C" GPRINT:inavg:"Inavg %2.1lf C" GPRINT:incur:"Innow %2.1lf C" \
2>&1 > /dev/null

wbaz.sh:

#!/usr/bin/bash

/opt/csw/bin/rrdtool graph weatherweek.png  -z -e now -s end-1week -f "" -t "Temperature - Last week"  -E  -a PNG DEF:tmax=weather.rrd:temp:MAX DEF:indoor=weather_indoor.rrd:temp:AVERAGE DEF:tmin=weather.rrd:temp:MIN DEF:temp=weather.rrd:temp:AVERAGE  LINE1:indoor#0000FF LINE1:temp#FF0000:""  VDEF:D=temp,LSLSLOPE VDEF:H=temp,LSLINT CDEF:projection=temp,POP,D,COUNT,*,H,+  LINE1:projection#BB2030:"" VDEF:tempmax=tmax,MAXIMUM VDEF:tempmin=tmin,MINIMUM GPRINT:tempmin:"Min %2.1lf C" LINE0.5:tempmax#6699FF:"" LINE0.5:tempmin#6699FF GPRINT:tempmax:"Max %2.1lf C" VDEF:tempavg=temp,AVERAGE GPRINT:tempavg:"Avg %2.1lf C"  VDEF:tempcur=temp,LAST GPRINT:tempcur:"Time %H.%M":strftime 2>&1 > /dev/null

mbaz.sh:

#!/bin/sh

/opt/csw/bin/rrdtool graph weathermonth.png -z  -e now -s end-1month -f "" -t "Temperature - Last month"  -E  -a PNG \
DEF:indoor=weather_indoor.rrd:temp:AVERAGE \
LINE1:indoor#0000FF \
DEF:tmax=weather.rrd:temp:MAX \
DEF:tmin=weather.rrd:temp:MIN \
DEF:temp=weather.rrd:temp:AVERAGE LINE1:temp#FF0000:"" \
VDEF:tempmax=tmax,MAXIMUM \
VDEF:tempmin=tmin,MINIMUM \
GPRINT:tempmin:"Min %2.1lf C" \
GPRINT:tempmax:"Max %2.1lf C" \
VDEF:tempavg=temp,AVERAGE GPRINT:tempavg:"Avg %2.1lf C"  \
VDEF:tempcur=temp,LAST GPRINT:tempcur:"Time %H.%M":strftime \
DEF:ymonth=weather.rrd:temp:AVERAGE:end=now-1y:start=end-1y \
SHIFT:ymonth:31556926 \
LINE1:ymonth#00FF00:lastyear \
2>&1 > /dev/null

Jag har även två script som visar ALL data:

Nattligt cronjob, "nightlycron.sh", körs kl 00:00 varje natt

#!/usr/bin/bash

#
# script to collect the max, avg, min data during the day and write it to a log
#
export PATH=/usr/local/bin:/opt/csw/bin:$PATH

cd <path to directory with data>

rm -f temp.tmp
rm -f tempp.tmp

#
# calc the data on daily basis
#

firstdata=0

for midnight in `sed 's/^/@/' < temperatures.log | cut -d' ' -f1 | gdate -f - +%y%m%d | uniq | gdate -f - +%s`; do

    if [ $firstdata = 0 ]; then firstdata=$midnight; fi

        foo=`gdate -d @$midnight`
        echo "$midnight: $foo"

    awk "BEGIN {c=0;sum=0;max=-100;min=100;start=$midnight;stop=start+86400} \$1 > start && \$1 < stop {apa=\$2;sum=sum+apa;c=c+1;if(max<apa) max=apa; if(min>apa) min=apa;} END {print start\",\"max\",\"sum/c\",\"min}" < temperatures.log >> tempp.tmp

done

#
# remove bad datapoints
#

grep -v "0.0,0,0.0" tempp.tmp > temp.tmp

#
# and plot the graph
#

/opt/csw/bin/gnuplot yearly.gnuplot

# update image
wget http://<www>/<weatherpath>/graph.php -o /dev/null -O /dev/null

yearly.gnuplot:

set term png size 481,179
set datafile separator ","
#set xrange [1208948000:1211022500]
set output "weatheryear.png"
set timefmt "%s"
set format x "%b %y"
set xtics nomirror rotate
set xdata time
#unset tics
unset key
plot "temp.tmp" using 1:2 with lines, "temp.tmp" using 1:3 with lines, "temp.tmp" using 1:4 with lines

Patch

[redigera]
--- sendwx.c.orig       2008-05-17 13:46:46.814612534 +0200
+++ sendwx.c    2008-05-17 13:37:15.360145696 +0200
@@ -256,6 +256,8 @@
   static rainlist remote_list24 = {NULL, 0, 0, RAININT_TIMEOUT_24HR} ;
   static int remote_rain = 0 ;

+       return 1;
+
   char *start = NULL, *end = NULL ;
   int i ;

@@ -540,7 +542,7 @@
     /*if (!strstr(session->body, session->reply))*/
     {
       /* Not the expected reply */
-      werr(WERR_WARNING, _("URL fetch failed: %s"), session->body) ;
+      werr(WERR_DEBUG0, _("URL fetch failed: %s"), session->body) ;
     }
     else
     {
@@ -665,38 +667,49 @@
     sprintf(urlstring, "%s?Mode=0&WID=%s&Dat=%d"
       "&Tem=%.1f&WSp=%.0f&WDr=%d"
       "&RSp=%.2f&Dar=%d"
-      "&Cod=%s&Lon=%.6f&Lat=%.6f",
+      "&Cod=%s&Lon=%.6f&Lat=%.6f&Tem2=%.1f",
       setup_httpdallas,
       Wid,
       (int) convert_time(means->meanTime),
+/*
       convert_temp(weather_primary_T(means), setup_f),
+*/
+        means->meanT[0],
       convert_speed(means->meanWs, setup_f),
       means->point,
       convert_mm(means->rain, !setup_f),
       (int) convert_time(ws.t_rain[0]),
       (setup_f)?"English":"Metric",
       setup_longitude,
-      setup_latitude
+      setup_latitude,means->meanT[1]
       ) ;
   }
   else
   {
     sprintf(urlstring, "%s?Mode=0&WID=%s&Dat=%d"
       "&Tem=%.1f&WSp=%.0f&WDr=%d&Cod=%s"
-      "&Lon=%.6f&Lat=%.6f",
+      "&Lon=%.6f&Lat=%.6f&Tem2=%.1f",
       setup_httpdallas,
       Wid,
       (int) convert_time(means->meanTime),
+/*
       convert_temp(weather_primary_T(means), setup_f),
+*/
+        means->meanT[0],
       convert_speed(means->meanWs, setup_f),
       means->point,
       convert_mm(means->rain, !setup_f),
       (int) convert_time(ws.t_rain[0]),
       (setup_f)?"English":"Metric",
       setup_longitude,
-      setup_latitude
+      setup_latitude,means->meanT[1]
       ) ;
   }
   else
   {
     sprintf(urlstring, "%s?Mode=0&WID=%s&Dat=%d"
       "&Tem=%.1f&WSp=%.0f&WDr=%d&Cod=%s"
-      "&Lon=%.6f&Lat=%.6f",
+      "&Lon=%.6f&Lat=%.6f&Tem2=%.1f",
       setup_httpdallas,
       Wid,
       (int) convert_time(means->meanTime),
+/*
       convert_temp(weather_primary_T(means), setup_f),
+*/
+        means->meanT[0],
+
       convert_speed(means->meanWs, setup_f),
       means->point,
       (setup_f)?"English":"Metric",
       setup_longitude,
-      setup_latitude
+      setup_latitude,means->meanT[1]
       ) ;
   }

+       //puts(urlstring);
+       //exit(0);
+
   set_old_locale();
+
 }

 static void