2
0
mirror of https://github.com/fhem/fhem-mirror.git synced 2025-04-14 21:49:12 +00:00

Lot of small changes

git-svn-id: https://svn.fhem.de/fhem/trunk@605 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
rudolfkoenig 2010-03-23 09:03:04 +00:00
parent b26b8a89cc
commit 7eb5d9deb1
7 changed files with 224 additions and 153 deletions

View File

@ -12,12 +12,9 @@ sub KM271_CloseDev($);
sub KM271_SimpleWrite(@);
sub KM271_SimpleRead($);
sub KM271_crc($);
sub KM271_setbits($$);
sub KM271_setbits($$$);
sub KM271_Reading($$);
my %sets = (
);
my $stx = pack('H*', "02");
my $dle = pack('H*', "10");
my $etx = pack('H*', "03");
@ -31,110 +28,131 @@ my $logmode = pack('H*', "EE00001003FD");
# http://www.buderus.de/pdf/unterlagen/0063061377.pdf
my %km271_trhash =
(
"8000" => 'Betriebswerte_1_HK1', # 76, 4 [repeat]
"8001" => 'Betriebswerte_2_HK1', # 0 (22:33), 2 (7:33)
"8002" => 'Vorlaufsolltemperatur_HK1', # 50-65
"8003" => 'Vorlaufisttemperatur_HK1', # Schwingt um soll herum
"8004" => 'Raumsolltemperatur_HK1', # 34 (22:33) 42 (7:33)
"8005" => 'Raumisttemperatur_HK1',
"8006" => 'Einschaltoptimierungszeit_HK1',
"8007" => 'Ausschaltoptimierungszeit_HK1',
"8008" => 'Pumpenleistung_HK1', # 0/100 == Ladepumpe
"8009" => 'Mischerstellung_HK1',
"800a" => 'nicht_belegt',
"800b" => 'nicht_belegt',
"800c" => 'Heizkennlinie_HK1_bei_+_10_Grad', # bei Umschaltung tag/nacht
"800d" => 'Heizkennlinie_HK1_bei_0_Grad', # bei Umschaltung tag/nacht
"800e" => 'Heizkennlinie_HK1_bei_-_10_Grad', # bei Umschaltung tag/nacht
"800f" => 'nicht_belegt',
"8010" => 'nicht_belegt',
"8011" => 'nicht_belegt',
"007e" => "Manuell_WW",
"0085" => "Manuell_ZirkulationsPumpe",
"0093" => "Manuell_Uhrzeit",
"8112" => 'Betriebswerte_1_HK2',
"8113" => 'Betriebswerte_1_HK2',
"8114" => 'Vorlaufsolltemperatur_HK2',
"8115" => 'Vorlaufisttemperatur_HK2',
"8116" => 'Raumsolltemperatur_HK2',
"8117" => 'Raumisttemperatur_HK2',
"8118" => 'Einschaltoptimierungszeit_HK2',
"8119" => 'Ausschaltoptimierungszeit_HK2',
"811a" => 'Pumpenleistung_HK2',
"811b" => 'Mischerstellung_HK2',
"811c" => 'nicht_belegt',
"811d" => 'nicht_belegt',
"811e" => 'Heizkennlinie_HK2_bei_+_10_Grad', # == HK1 - (1 bis 3)
"811f" => 'Heizkennlinie_HK2_bei_0_Grad', # == HK1 - (1 bis 3)
"8120" => 'Heizkennlinie_HK2_bei_-_10_Grad', # == HK1 - (1 bis 3)
"8121" => 'nicht_belegt',
"8122" => 'nicht_belegt',
"8123" => 'nicht_belegt',
"0300" => "Tagwechsel_1",
"0307" => "Tagwechsel_2",
"030e" => "Tagwechsel_3",
"0315" => "Tagwechsel_4",
"8424" => 'Betriebswerte_1_WW',
"8425" => 'Betriebswerte_2_WW', # 0 64 96 104 225 228
"8426" => 'Warmwassersolltemperatur', # 10/55
"8427" => 'Warmwasseristtemperatur', # 32-55
"8428" => 'Warmwasseroptimierungszeit',
"8429" => 'Ladepumpe', # 0 1 (an/aus?)
"0400" => "NoData",
"8000" => 'HK1_Betriebswerte1', # 76, 4 [repeat]
"8001" => 'HK1_Betriebswerte2', # 0 (22:33), 2 (7:33)
"8002" => 'HK1_Vorlaufsolltemperatur', # 50-65
"8003" => 'HK1_Vorlaufisttemperatur', # Schwingt um soll herum
"8004" => 'HK1_Raumsolltemperatur', # 34 (22:33) 42 (7:33)
"8005" => 'HK1_Raumisttemperatur',
"8006" => 'HK1_Einschaltoptimierungszeit',
"8007" => 'HK1_Ausschaltoptimierungszeit',
"8008" => 'HK1_Pumpenleistung', # 0/100 == Ladepumpe
"8009" => 'HK1_Mischerstellung',
"800c" => 'HK1_Heizkennlinie_bei_+_10_Grad', # bei Umschaltung tag/nacht
"800d" => 'HK1_Heizkennlinie_bei_0_Grad', # bei Umschaltung tag/nacht
"800e" => 'HK1_Heizkennlinie_bei_-_10_Grad', # bei Umschaltung tag/nacht
"8112" => 'HK2_Betriebswerte1',
"8113" => 'HK2_Betriebswerte2',
"8114" => 'HK2_Vorlaufsolltemperatur',
"8115" => 'HK2_Vorlaufisttemperatur',
"8116" => 'HK2_Raumsolltemperatur',
"8117" => 'HK2_Raumisttemperatur',
"8118" => 'HK2_Einschaltoptimierungszeit',
"8119" => 'HK2_Ausschaltoptimierungszeit',
"811a" => 'HK2_Pumpenleistung',
"811b" => 'HK2_Mischerstellung',
"811e" => 'HK2_Heizkennlinie_bei_+_10_Grad', # == HK1 - (1 bis 3 Grad)
"811f" => 'HK2_Heizkennlinie_bei_0_Grad', # == HK1 - (1 bis 3 Grad)
"8120" => 'HK2_Heizkennlinie_bei_-_10_Grad', # == HK1 - (1 bis 3 Grad)
# 1377, page 11
"8424" => 'WW_Betriebswerte1',
"8425" => 'WW_Betriebswerte2', # 0 64 96 104 225 228
"8426" => 'WW_Solltemperatur', # 10/55
"8427" => 'WW_Isttemperatur', # 32-55
"8428" => 'WW_Einschaltoptimierungszeit',
"8429" => 'WW_Ladepumpe', # 0 1 (an/aus?)
# 1377, page 13
"882a" => 'Kesselvorlaufsolltemperatur',
"882b" => 'Kesselvorlaufisttemperatur', # == Vorlaufisttemperatur_HK1
"882c" => 'Brennereinschalttemperatur', # 5-81
"882d" => 'Brennerausschalttemperatur', # 19-85
"882e" => 'Kesselintegral_1', # 0-23
"882f" => 'Kesselintegral_2', # 0-255
"8830" => 'Kesselfehler',
"8831" => 'Kesselbetrieb', # 0 2 32 34
"8832" => 'Brenneransteuerung', # 0 1 (an/aus?)
"882a" => 'Kessel_Vorlaufsolltemperatur',
"882b" => 'Kessel_Vorlaufisttemperatur', # == Vorlaufisttemperatur_HK1
"882c" => 'Brenner_Einschalttemperatur', # 5-81
"882d" => 'Brenner_Ausschalttemperatur', # 19-85
"882e" => 'Kessel_IntegralHB', # 0-23
"882f" => 'Kessel_IntegralLB', # 0-255
"8830" => 'Kessel_Fehler',
"8831" => 'Kessel_Betrieb', # 0 2 32 34
"8832" => 'Brenner_Ansteuerung', # 0 1 (an/aus?)
"8833" => 'Abgastemperatur',
"8834" => 'modulare_Brenner_Stellwert',
"8835" => 'nicht_belegt',
"8836" => 'Brennerlaufzeit_1_Minuten_Byte2',
"8837" => 'Brennerlaufzeit_1_Minuten_Byte1', # 176
"8838" => 'Brennerlaufzeit_1_Minuten_Byte0', # 0-255 (Minuten)
"8839" => 'Brennerlaufzeit_2_Minuten_Byte2',
"883a" => 'Brennerlaufzeit_2_Minuten_Byte1',
"883b" => 'Brennerlaufzeit_2_Minuten_Byte0',
"8834" => 'Brenner_Stellwert',
"8836" => 'Brenner_Laufzeit1_Minuten2',
"8837" => 'Brenner_Laufzeit1_Minuten1', # 176
"8838" => 'Brenner_Laufzeit1_Minuten0', # 0-255 (Minuten)
"8839" => 'Brenner_Laufzeit2_Minuten2',
"883a" => 'Brenner_Laufzeit2_Minuten1',
"883b" => 'Brenner_Laufzeit2_Minuten0',
# 1377, page 16
"893c" => 'Aussentemperatur', # 0 1 254 255
"893d" => 'gedaempfte_Aussentemperatur', # 0 1 2
"893d" => 'Aussentemperatur_gedaempft', # 0 1 2
"893e" => 'Versionsnummer_VK',
"893f" => 'Versionsnummer_NK',
"8940" => 'Modulkennung',
"8941" => 'nicht_belegt',
);
# Do not generate fhem events for the following high volume telegrams
# the % represents the relative nr of messages in an unfiltered stream.
# You can switch them on with attr all_km271_events
my %km271_ignore = (
"Vorlaufisttemperatur_HK1" => 1, # 23%
my %km271_noevent = (
"HK1_Vorlaufisttemperatur" => 1, # 23% of all messages
"HK2_Vorlaufisttemperatur" => 1,
"Kesselvorlaufisttemperatur" => 1, # 23%, same as Vorlaufisttemperatur_HK1
"Kesselintegral_1" => 1, # 8%, ??
"Kesselintegral_2" => 1, # 38%, ??
"Kessel_IntegralHB" => 1, # 8%, ??
"Kessel_IntegralLB" => 1, # 38%, ??
);
my @km271_Betriebswerte_1_HK = (
my @km271_HK_Betriebswerte1 = (
"Ausschaltoptimierung", "Einschaltoptimierung", "Automatik",
"Warmwasservorrang", "Estrichtrocknung", "Ferien", "Frostschutz", "Manuell",
);
my @km271_Betriebswerte_2_HK = (
my @km271_HK_Betriebswerte2 = (
"Sommer", "Tag", "keine Kommunikation mit FB", "FB fehlerhhaft",
"Fehler Vorlauffühler", "maximaler Vorlauf", "externer Störeingang", "frei",
);
my @km271_Betriebswerte_1_WW = (
my @km271_WW_Betriebswerte1 = (
"Automatik", "Desinfektion", "Nachladung", "Ferien", "Fehler Desinfektion",
"Fehler Fuehler", "Fehler WW bleibt kalt", "Fehler Anode",
);
my @km271_Betriebswerte_2_WW = (
my @km271_WW_Betriebswerte2 = (
"Laden", "Manuell", "Nachladen", "Ausschaltoptimierung",
"Einschaltoptimierung", "Tag", "Warm", "Vorrang",
);
my @km271_Kesselbetrieb = (
my @km271_Kessel_Betrieb = (
"Tag", "Automatik", "Sommer", "Bit3", "Bit4", "Bit5", "Bit6", "Bit7",
);
my @km271_WW_Ladepumpe = (
"Ladepumpe", "Zirkulationspumpe", "Absenkung Solar",
"Bit3", "Bit4", "Bit5", "Bit6", "Bit7",
);
my %km271_set_betriebsart = (
"manuell_nacht"=>0,
"manuell_tag" =>1,
"automatik" =>2,
);
my %km271_sets = (
"hk1_nachtsoll" => "07006565%02x656565", # 0.5 celsius
"hk1_tagsoll" => "0700656565%02x6565", # 0.5 celsius
"hk1_betriebsart" => "070065656565%02x65",
"ww_soll" => "0C07656565%02x6565", # 1.0 celsius
"ww_betriebsart" => "0C0E%02x6565656565",
);
@ -150,6 +168,8 @@ KM271_Initialize($)
$hash->{UndefFn} = "KM271_Undef";
$hash->{SetFn} = "KM271_Set";
$hash->{AttrList}= "do_not_notify:1,0 all_km271_events loglevel:0,1,2,3,4,5,6";
my @a = ();
$hash->{SENDBUFFER} = \@a;
}
#####################################
@ -193,12 +213,29 @@ KM271_Set($@)
my ($hash, @a) = @_;
return "\"set KM271\" needs at least one parameter" if(@a < 2);
return "Unknown argument $a[1], choose one of " . join(" ", sort keys %sets)
if(!defined($sets{$a[1]}));
my $name = shift @a;
my $type = shift @a;
my $arg = join("", @a);
my $fmt = $km271_sets{$a[1]};
return "Unknown argument $a[1], choose one of " .
join(" ", sort keys %km271_sets) if(!defined($fmt));
my $val = $a[2];
my $numeric_arg = ($val =~ m/^[.0-9]+$/);
if($a[1] =~ m/^hk.*soll$/) {
return "Argument must be numeric (between 10 and 30)" if(!$numeric_arg);
$val *= 2;
}
if($a[1] =~ m/^ww.*soll$/) {
return "Argument must be numeric (between 30 and 60)" if(!$numeric_arg);
}
if($a[1] =~ m/_betriebsart/) {
$val = $km271_set_betriebsart{$val};
return "Unknown arg, use one of " .
join(" ", sort keys %km271_set_betriebsart) if(!defined($val));
}
my $data = sprintf($fmt, $val);
push @{$hash->{SENDBUFFER}}, $data;
KM271_SimpleWrite($hash, $stx) if(!$hash->{WAITING});
return undef;
}
@ -211,6 +248,7 @@ KM271_Read($)
{
my ($hash) = @_;
my $name = $hash->{NAME};
my ($data, $crc);
my $buf = KM271_SimpleRead($hash);
Log GetLogLevel($name,5), "KM271 RAW: " . unpack('H*', $buf);
@ -221,86 +259,125 @@ KM271_Read($)
return;
}
$buf = unpack('H*', $buf);
if($buf eq "02") {
if($buf eq "02") { # KM271: Want to send
$hash->{PARTIAL} = "";
KM271_SimpleWrite($hash, $dle);
KM271_SimpleWrite($hash, $dle); # We are ready
$hash->{WAITING} = 1;
return;
}
if(!$hash->{WAITING}) { # Send data
if($buf eq "10") {
if($hash->{DATASENT}) { # ACK Data
delete($hash->{DATASENT});
return;
}
$data = pop @{ $hash->{SENDBUFFER} };
$data =~ s/10/1010/g;
$crc = KM271_crc($data);
KM271_SimpleWrite($hash, $data."1003$crc"); # Send the data
$hash->{DATASENT} = 1;
}
if($buf eq "15" && $hash->{DATASENT}) { # NACK from the KM271
Log 1, "$name: NACK!";
delete($hash->{DATASENT});
return;
}
}
$hash->{PARTIAL} .= $buf;
my $len = length($hash->{PARTIAL});
return if($hash->{PARTIAL} !~ m/^(.*)1003(..)$/);
my ($data, $crc) = ($1, $2);
($data, $crc) = ($1, $2);
if(KM271_crc($data) ne $crc) {
Log 1, "Wrong CRC in $hash->{PARTIAL}: $crc vs. ". KM271_crc($data);
$hash->{PARTIAL} = "";
KM271_SimpleWrite($hash, $nak);
return;
}
KM271_SimpleWrite($hash, $dle);
KM271_SimpleWrite($hash, $dle); # Data received ok
delete($hash->{WAITING});
if($hash->{SENDBUFFER}) {
KM271_SimpleWrite($hash, $stx)
}
$data =~ s/1010/10/g;
if($data =~ m/^(8...)(..)/) {
my ($fn, $arg) = ($1, $2);
my $msg = $km271_trhash{$fn};
$msg = "UNKNOWN_$fn" if(!$msg);
my $tn = TimeNow();
my $val = hex($arg);
my $ignore = $km271_ignore{$msg};
if($msg =~ m/Aussentemperatur/) {
$val = $val-256 if($val > 128);
if($data !~ m/^(....)(.*)/) {
Log 1, "$name: Bogus message: $data";
return;
}
} elsif($msg =~ m/Brennerlaufzeit_(.)_Minuten_Byte(.)/) {
my ($idx, $no) = ($1, $2);
my ($fn, $arg) = ($1, $2);
my $msg = $km271_trhash{$fn};
$msg = "UNKNOWN_$fn" if(!$msg);
my $tn = TimeNow();
my $val = unpack('H*', $arg);
my $gen_notify = $km271_noevent{$msg} ? 0 : 1;
$gen_notify = KM271_attr($name, "all_km271_events")
if(!$gen_notify);
if($no == 2 || $no == 1) {
$ignore = 1;
} else {
$msg = "Brennerlaufzeit_${idx}_Minuten";
$val = KM271_Reading($hash, $msg . "_Byte2") * 65536 +
KM271_Reading($hash, $msg . "_Byte1") * 256 +
$val;
}
if($msg eq "NoData") {
$gen_notify = 0;
} elsif($msg =~ m/Betriebswerte_1_HK/) {
$val = KM271_setbits($val, \@km271_Betriebswerte_1_HK);
} elsif($msg =~ m/^UNKNOWN/) {
$val = $data;
$gen_notify = 0;
} elsif($msg =~ m/Aussentemperatur/) {
$val = $val-256 if($val > 128);
} elsif($msg =~ m/Betriebswerte_2_HK/) {
$val = KM271_setbits($val, \@km271_Betriebswerte_2_HK);
} elsif($msg =~ m/Brenner_Laufzeit(.)_Minuten(.)/) {
my ($idx, $no) = ($1, $2);
} elsif($msg =~ m/Betriebswerte_1_WW/) {
$val = KM271_setbits($val, \@km271_Betriebswerte_1_WW);
} elsif($msg =~ m/Betriebswerte_2_WW/) {
$val = KM271_setbits($val, \@km271_Betriebswerte_2_WW);
} elsif($msg =~ m/Brenneransteuerung/) {
$val = ($val ? "an" : "aus");
} elsif($msg =~ m/Kesselbetrieb/) {
$val = KM271_setbits($val, \@km271_Kesselbetrieb);
if($no == 2 || $no == 1) {
$gen_notify = 0;
} else {
$msg = "Brenner_Laufzeit${idx}_Minuten";
$val = KM271_Reading($hash, $msg . "2") * 65536 +
KM271_Reading($hash, $msg . "1") * 256 +
$val;
}
Log GetLogLevel($name,4), "KM271 $name: $msg $val";
$hash->{READINGS}{$msg}{TIME} = $tn;
$hash->{READINGS}{$msg}{VAL} = $val;
if(KM271_attr($name, "all_km271_events") || !$ignore) {
DoTrigger($name, "$msg: $val");
}
} elsif($msg =~ m/HK._Betriebswerte/) {
$val = KM271_setbits($val, \@km271_HK_Betriebswerte1, "leer");
} elsif($data eq "04000701c4024192") {
# No data message
} elsif($msg =~ m/HK._Betriebswerte2/) {
$val = KM271_setbits($val, \@km271_HK_Betriebswerte2, "leer");
} else {
Log 1, "$name: UNKNOWN $data";
} elsif($msg =~ m/WW_Betriebswerte1/) {
$val = KM271_setbits($val, \@km271_WW_Betriebswerte1, "aus");
} elsif($msg =~ m/WW_Betriebswerte2/) {
$val = KM271_setbits($val, \@km271_WW_Betriebswerte2, "aus");
} elsif($msg =~ m/Brenner_Ansteuerung/) {
$val = ($val ? "an" : "aus");
} elsif($msg =~ m/Kessel_Betrieb/) {
$val = KM271_setbits($val, \@km271_Kessel_Betrieb, "aus");
} elsif($msg =~ m/WW_Ladepumpe/) {
$val = KM271_setbits($val, \@km271_WW_Ladepumpe, "aus");
} elsif($msg =~ m/HK?_Raum.*temperatur/) {
$val = $val/2;
}
$val = $arg if(length($arg) > 2);
Log GetLogLevel($name,4), "KM271 $name: $msg $val";
$hash->{READINGS}{$msg}{TIME} = $tn;
$hash->{READINGS}{$msg}{VAL} = $val;
DoTrigger($name, "$msg: $val") if($gen_notify);
$hash->{PARTIAL} = "";
}
@ -321,7 +398,7 @@ sub
KM271_SimpleWrite(@)
{
my ($hash, $msg) = @_;
$hash->{Dev}->write($msg);
$hash->{Dev}->write($msg) if($hash->{DeviceName});
}
########################
@ -393,18 +470,21 @@ KM271_OpenDev($)
$po->parity('none');
$po->stopbits(1);
$po->handshake('none');
$po->write($logmode);
$hash->{STATE} = "Initialized";
#$po->write($logmode);
push @{$hash->{SENDBUFFER}}, "EE0000";
KM271_SimpleWrite($hash, $stx);
Log 3, "$dev opened";
return undef;
}
sub
KM271_setbits($$)
KM271_setbits($$$)
{
my ($val, $arr) = @_;
my ($val, $arr, $nulltxt) = @_;
my $bit = 1;
my @ret;
@ -412,7 +492,7 @@ KM271_setbits($$)
push(@ret, $arr->[$idx]) if($val & $bit);
$bit *= 2;
}
return "keine Bits gesetzt" if(!@ret);
return $nulltxt if(!@ret);
return join(",", @ret);
}

View File

@ -506,7 +506,7 @@ FHT_Parse($$)
$nc++;
}
if(substr($msg,24,1) eq "7") {
if(substr($msg,24,1) eq "7") { # Do not store FHZ acks.
$cmd = "FHZ:$cmd";
} else {
$def->{READINGS}{$cmd}{TIME} = $tn;

View File

@ -4,9 +4,6 @@ package main;
use strict;
use warnings;
# Adjust TOTAL to you meter:
# {$defs{emwz}{READINGS}{basis}{VAL}=<meter>/<corr2>-<total_cnt> }
#####################################
sub
CUL_RFR_Initialize($)
@ -96,6 +93,9 @@ CUL_RFR_Parse($$)
elsif($smsg =~ m/^K/) { $hash->{NR_KMSG}++ }
else { $hash->{NR_RMSG}++ }
$smsg = $1 if($smsg =~ m/^(E[0-9A-F]{20})[REFHKT]/); # Fixing a CUL/RFR bug
$smsg = $1 if($smsg =~ m/^(R[0-9A-F]{12})[REFHKT]/);
CUL_Parse($hash, $iohash, $hash->{NAME}, $smsg, "X21");
return "";
}

View File

@ -347,6 +347,7 @@ FileLog_Get($@)
$data{"min$j"} = $min[$i] == 999999 ? "undef" : $min[$i];
$data{"max$j"} = $max[$i] == -999999 ? "undef" : $max[$i];
$data{"avg$j"} = $cnt[$i] ? sprintf("%0.1f", $sum[$i]/$cnt[$i]) : "undef";
$data{"sum$j"} = $sum[$i];
$data{"cnt$j"} = $cnt[$i] ? $cnt[$i] : "undef";
$data{"currval$j"} = $lastv[$i];
$data{"currdate$j"} = $lastd[$i];

View File

@ -93,7 +93,7 @@ autocreate_Notify($$)
my $flname = "FileLog_$name";
my ($gplot, $filter) = ("", $name);
foreach my $k (keys %flogpar) {
next if("$type:$name" !~ m/^$k$/);
next if("$type:$name" !~ m/^$k$/);
$gplot = $flogpar{$k}{GPLOT};
$filter = replace_wildcards($hash, $flogpar{$k}{FILTER});
}

View File

@ -89,11 +89,10 @@
iPhone frontends:
<a href="http://www.gschaden.com/wp/2009/01/18/fhem-iphone-gateway/">
fhemgw</a> or
fhemgw</a>,
<a href="http://www.dhs-computertechnik.de/support-iphone.html">
dhs-computertechnik</a>
</a>
dhs-computertechnik</a> or
<a href="http://code.google.com/p/phyfhem/">phyfhem</a>
</ul>

View File

@ -20,7 +20,6 @@ set yrange [0:]
#FileLog 4:Warmwasseristtemperatur:0:
#FileLog 4:Brennerlaufzeit:0:delta-h
#FileLog 4:Brennerlaufzeit:0:delta-d
plot "<IN>" using 1:4 axes x1y2 title 'WW-Temp' with lines lw 2,\
"<grep Brennerlaufzeit <IN> | perl -ane '\
@ -30,12 +29,4 @@ plot "<IN>" using 1:4 axes x1y2 title 'WW-Temp' with lines lw 2,\
if($lv) { $hv += ($F[3]-$lv); }\
$lh = $a[1]; $ld = $a[0]; $lv = $F[3];\
END { printf(\"${ld}_$lh:30:00 %f\n\", $hv) }'"\
using 1:2 axes x1y1 title 'Runtime/h (Min)' with histeps,\
"<grep Brennerlaufzeit <IN> | perl -ane '\
@a = split(\"[_]\", $F[0]);\
if(defined($ld) && $ld ne $a[0]) {\
printf(\"${ld}_12:00:00 %f\n\", $dv); $dv = 0; }\
if($lv) { $dv += ($F[3]-$lv); }\
$ld = $a[0]; $lv = $F[3];\
END {printf(\"${ld}_12:00:00 %f\n\", $dv)}'"\
using 1:2 axes x1y1 title 'Runtime/day (Min)' with histeps
using 1:2 axes x1y1 title 'Runtime/h (Min)' with histeps