mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-03-10 03:06:37 +00:00
feature: DbLog: jokers "%" in device/reading definition are now possible
feature: Text2Speech: Definition of mp3files with a custom templatedefinition. git-svn-id: https://svn.fhem.de/fhem/trunk@4747 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
8fdbb1abe3
commit
23ea60a1c6
@ -1,6 +1,7 @@
|
||||
# Add changes at the top of the list. Keep it in ASCII, and 80-char wide.
|
||||
# Do not insert empty lines here, update check depends on it.
|
||||
- SVN
|
||||
- feature: DbLog: jokers "%" in device/reading definition are now possible
|
||||
- feature: SYSMON: new CPU Statistics and Plots
|
||||
- feature: changed 10_OWServer.pm and 11_OWDevice.pm to use
|
||||
NOTIFYDEV (justme1968)
|
||||
|
@ -6,7 +6,7 @@
|
||||
# written by Dr. Boris Neubert 2007-12-30
|
||||
# e-mail: omega at online dot de
|
||||
#
|
||||
# modified by Tobias Faust 2012-06-26
|
||||
# modified and maintained by Tobias Faust since 2012-06-26
|
||||
# e-mail: tobias dot faust at online dot de
|
||||
#
|
||||
##############################################
|
||||
@ -17,11 +17,8 @@ use warnings;
|
||||
use DBI;
|
||||
use Data::Dumper;
|
||||
|
||||
sub DbLog($$$);
|
||||
|
||||
################################################################
|
||||
sub
|
||||
DbLog_Initialize($)
|
||||
sub DbLog_Initialize($)
|
||||
{
|
||||
my ($hash) = @_;
|
||||
|
||||
@ -36,8 +33,7 @@ DbLog_Initialize($)
|
||||
}
|
||||
|
||||
###############################################################
|
||||
sub
|
||||
DbLog_Define($@)
|
||||
sub DbLog_Define($@)
|
||||
{
|
||||
my ($hash, $def) = @_;
|
||||
my @a = split("[ \t][ \t]*", $def);
|
||||
@ -64,8 +60,7 @@ DbLog_Define($@)
|
||||
}
|
||||
|
||||
#####################################
|
||||
sub
|
||||
DbLog_Undef($$)
|
||||
sub DbLog_Undef($$)
|
||||
{
|
||||
my ($hash, $name) = @_;
|
||||
my $dbh= $hash->{DBH};
|
||||
@ -79,8 +74,7 @@ DbLog_Undef($$)
|
||||
# DbLog-Instanz aufgerufen
|
||||
#
|
||||
################################################################
|
||||
sub
|
||||
DbLog_Attr(@)
|
||||
sub DbLog_Attr(@)
|
||||
{
|
||||
my @a = @_;
|
||||
my $do = 0;
|
||||
@ -101,8 +95,7 @@ DbLog_Attr(@)
|
||||
# Parsefunktion, abhaengig vom Devicetyp
|
||||
#
|
||||
################################################################
|
||||
sub
|
||||
DbLog_ParseEvent($$$)
|
||||
sub DbLog_ParseEvent($$$)
|
||||
{
|
||||
my ($device, $type, $event)= @_;
|
||||
my @result;
|
||||
@ -159,6 +152,14 @@ DbLog_ParseEvent($$$)
|
||||
}
|
||||
}
|
||||
|
||||
# FBDECT
|
||||
elsif (($type eq "FBDECT")) {
|
||||
if ( $value=~/([\.\d]+)\s([a-z])/i ) {
|
||||
$value = $1;
|
||||
$unit = $2;
|
||||
}
|
||||
}
|
||||
|
||||
# MAX
|
||||
elsif(($type eq "MAX")) {
|
||||
$unit= "°C" if(lc($reading) =~ m/temp/);
|
||||
@ -339,6 +340,60 @@ DbLog_ParseEvent($$$)
|
||||
return @result;
|
||||
}
|
||||
|
||||
################################################################
|
||||
#
|
||||
# param1: hash
|
||||
# param2: DbLogType -> Current oder History oder Current/History
|
||||
# param4: Timestamp
|
||||
# param5: Device
|
||||
# param6: Type
|
||||
# param7: Event
|
||||
# param8: Reading
|
||||
# param9: Value
|
||||
# param10: Unit
|
||||
#
|
||||
################################################################
|
||||
sub DbLog_Push(@) {
|
||||
my ($hash, $DbLogType, $timestamp, $device, $type, $event, $reading, $value, $unit) = @_;
|
||||
|
||||
my $dbh= $hash->{DBH};
|
||||
$dbh->{RaiseError} = 1;
|
||||
|
||||
$dbh->begin_work();
|
||||
|
||||
my $sth_ih = $dbh->prepare_cached("INSERT INTO history (TIMESTAMP, DEVICE, TYPE, EVENT, READING, VALUE, UNIT) VALUES (?,?,?,?,?,?,?)") if (lc($DbLogType) =~ m(history) );
|
||||
my $sth_ic = $dbh->prepare_cached("INSERT INTO current (TIMESTAMP, DEVICE, TYPE, EVENT, READING, VALUE, UNIT) VALUES (?,?,?,?,?,?,?)") if (lc($DbLogType) =~ m(current) );
|
||||
my $sth_uc = $dbh->prepare_cached("UPDATE current SET TIMESTAMP=?, TYPE=?, EVENT=?, VALUE=?, UNIT=? WHERE (DEVICE=?) AND (READING=?)") if (lc($DbLogType) =~ m(current) );
|
||||
|
||||
# insert into history
|
||||
if (lc($DbLogType) =~ m(history) ) {
|
||||
my $rv_ih = $sth_ih->execute(($timestamp, $device, $type, $event, $reading, $value, $unit));
|
||||
}
|
||||
|
||||
# update or insert current
|
||||
if (lc($DbLogType) =~ m(current) ) {
|
||||
my $rv_uc = $sth_uc->execute(($timestamp, $type, $event, $value, $unit, $device, $reading));
|
||||
if ($rv_uc == 0) {
|
||||
my $rv_ic = $sth_ic->execute(($timestamp, $device, $type, $event, $reading, $value, $unit));
|
||||
}
|
||||
}
|
||||
|
||||
$dbh->commit();
|
||||
|
||||
if ($@) {
|
||||
Log3 $hash->{NAME}, 2, "DbLog: Failed to insert new readings into database: $@";
|
||||
$dbh->{RaiseError} = 0;
|
||||
$dbh->rollback();
|
||||
# reconnect
|
||||
$dbh->disconnect();
|
||||
DbLog_Connect($hash);
|
||||
}
|
||||
else {
|
||||
$dbh->{RaiseError} = 0;
|
||||
}
|
||||
|
||||
return $dbh->{RaiseError};
|
||||
}
|
||||
|
||||
################################################################
|
||||
#
|
||||
@ -346,13 +401,11 @@ DbLog_ParseEvent($$$)
|
||||
# aufgerufen
|
||||
#
|
||||
################################################################
|
||||
sub
|
||||
DbLog_Log($$)
|
||||
{
|
||||
sub DbLog_Log($$) {
|
||||
# Log is my entry, Dev is the entry of the changed device
|
||||
my ($log, $dev) = @_;
|
||||
my ($hash, $dev) = @_;
|
||||
|
||||
return undef if($log->{STATE} eq "disabled");
|
||||
return undef if($hash->{STATE} eq "disabled");
|
||||
|
||||
# name and type required for parsing
|
||||
my $n= $dev->{NAME};
|
||||
@ -362,25 +415,15 @@ DbLog_Log($$)
|
||||
#my ($sec,$min,$hr,$day,$mon,$yr,$wday,$yday,$isdst)= localtime(time);
|
||||
#my $ts= sprintf("%04d-%02d-%02d %02d:%02d:%02d", $yr+1900,$mon+1,$day,$hr,$min,$sec);
|
||||
|
||||
my $re = $log->{REGEXP};
|
||||
my $re = $hash->{REGEXP};
|
||||
my $max = int(@{$dev->{CHANGED}});
|
||||
my $ts_0 = TimeNow();
|
||||
my $now = gettimeofday(); # get timestamp in seconds since epoch
|
||||
my $DbLogExclude = AttrVal($dev->{NAME}, "DbLogExclude", undef);
|
||||
|
||||
my $dbh= $log->{DBH};
|
||||
$dbh->{RaiseError} = 1;
|
||||
|
||||
my $DbLogType = AttrVal($log->{NAME}, "DbLogType", "Current/History");
|
||||
my $DbLogType = AttrVal($hash->{NAME}, "DbLogType", "Current/History");
|
||||
|
||||
#one Transaction
|
||||
eval {
|
||||
$dbh->begin_work();
|
||||
|
||||
my $sth_ih = $dbh->prepare_cached("INSERT INTO history (TIMESTAMP, DEVICE, TYPE, EVENT, READING, VALUE, UNIT) VALUES (?,?,?,?,?,?,?)") if ($DbLogType =~ m(History) );
|
||||
my $sth_uc = $dbh->prepare_cached("UPDATE current SET TIMESTAMP=?, TYPE=?, EVENT=?, VALUE=?, UNIT=? WHERE (DEVICE=?) AND (READING=?)") if ($DbLogType =~ m(Current) );
|
||||
my $sth_ic = $dbh->prepare_cached("INSERT INTO current (TIMESTAMP, DEVICE, TYPE, EVENT, READING, VALUE, UNIT) VALUES (?,?,?,?,?,?,?)") if ($DbLogType =~ m(Current) );
|
||||
|
||||
#eval {
|
||||
for (my $i = 0; $i < $max; $i++) {
|
||||
my $s = $dev->{CHANGED}[$i];
|
||||
$s = "" if(!defined($s));
|
||||
@ -409,8 +452,8 @@ DbLog_Log($$)
|
||||
$DoIt = 0 if(!$v2[1] && $reading =~ m/^$v2[0]$/); #Reading matcht auf Regexp, kein MinIntervall angegeben
|
||||
if(($v2[1] && $reading =~ m/^$v2[0]$/) && ($v2[1] =~ m/^(\d+)$/)) {
|
||||
#Regexp matcht und MinIntervall ist angegeben
|
||||
my $lt = $defs{$dev->{NAME}}{Helper}{DBLOG}{$reading}{$log->{NAME}}{TIME};
|
||||
my $lv = $defs{$dev->{NAME}}{Helper}{DBLOG}{$reading}{$log->{NAME}}{VALUE};
|
||||
my $lt = $defs{$dev->{NAME}}{Helper}{DBLOG}{$reading}{$hash->{NAME}}{TIME};
|
||||
my $lv = $defs{$dev->{NAME}}{Helper}{DBLOG}{$reading}{$hash->{NAME}}{VALUE};
|
||||
$lt = 0 if(!$lt);
|
||||
$lv = "" if(!$lv);
|
||||
|
||||
@ -423,39 +466,14 @@ DbLog_Log($$)
|
||||
}
|
||||
next if($DoIt == 0);
|
||||
|
||||
$defs{$dev->{NAME}}{Helper}{DBLOG}{$reading}{$log->{NAME}}{TIME} = $now;
|
||||
$defs{$dev->{NAME}}{Helper}{DBLOG}{$reading}{$log->{NAME}}{VALUE} = $value;
|
||||
$defs{$dev->{NAME}}{Helper}{DBLOG}{$reading}{$hash->{NAME}}{TIME} = $now;
|
||||
$defs{$dev->{NAME}}{Helper}{DBLOG}{$reading}{$hash->{NAME}}{VALUE} = $value;
|
||||
|
||||
my @is= ($ts, $n, $t, $s, $reading, $value, $unit);
|
||||
|
||||
# insert into history
|
||||
if ($DbLogType =~ m(History) ) {
|
||||
my $rv_ih = $sth_ih->execute(@is);
|
||||
}
|
||||
|
||||
if ($DbLogType =~ m(Current) ) {
|
||||
# update or insert current
|
||||
my $rv_uc = $sth_uc->execute(($ts, $t, $s, $value, $unit, $n, $reading));
|
||||
if ($rv_uc == 0) {
|
||||
my $rv_ic = $sth_ic->execute(@is);
|
||||
}
|
||||
}
|
||||
DbLog_Push($hash, $DbLogType, $ts, $n, $t, $s, $reading, $value, $unit)
|
||||
|
||||
}
|
||||
}
|
||||
$dbh->commit();
|
||||
};
|
||||
if ($@) {
|
||||
Log3 $dev->{NAME}, 2, "DbLog: Failed to insert new readings into database: $@";
|
||||
$dbh->{RaiseError} = 0;
|
||||
$dbh->rollback();
|
||||
# reconnect
|
||||
$dbh->disconnect();
|
||||
DbLog_Connect($log);
|
||||
}
|
||||
else {
|
||||
$dbh->{RaiseError} = 0;
|
||||
}
|
||||
#};
|
||||
|
||||
return "";
|
||||
}
|
||||
@ -467,8 +485,7 @@ DbLog_Log($$)
|
||||
# uebergebenes SQL-Format: YYYY-MM-DD HH24:MI:SS
|
||||
#
|
||||
################################################################
|
||||
sub
|
||||
DbLog_explode_datetime($%) {
|
||||
sub DbLog_explode_datetime($%) {
|
||||
my ($t, %def) = @_;
|
||||
my %retv;
|
||||
|
||||
@ -489,20 +506,19 @@ DbLog_explode_datetime($%) {
|
||||
return %retv
|
||||
}
|
||||
|
||||
sub
|
||||
DbLog_implode_datetime($$$$$$) {
|
||||
sub DbLog_implode_datetime($$$$$$) {
|
||||
my ($year, $month, $day, $hour, $minute, $second) = @_;
|
||||
my $retv = $year."-".$month."-".$day." ".$hour.":".$minute.":".$second;
|
||||
|
||||
return $retv;
|
||||
}
|
||||
|
||||
################################################################
|
||||
#
|
||||
# Verbindung zur DB aufbauen
|
||||
#
|
||||
################################################################
|
||||
sub
|
||||
DbLog_Connect($)
|
||||
sub DbLog_Connect($)
|
||||
{
|
||||
my ($hash)= @_;
|
||||
|
||||
@ -575,6 +591,9 @@ DbLog_Connect($)
|
||||
#
|
||||
# Prozeduren zum Ausfuehren des SQLs
|
||||
#
|
||||
# param1: hash
|
||||
# param2: pointer : DBFilehandle
|
||||
# param3: string : SQL
|
||||
################################################################
|
||||
sub
|
||||
DbLog_ExecSQL1($$$)
|
||||
@ -618,6 +637,8 @@ DbLog_ExecSQL($$)
|
||||
#
|
||||
# GET Funktion
|
||||
# wird zb. zur Generierung der Plots implizit aufgerufen
|
||||
# infile : [-|current|history]
|
||||
# outfile: [-|ALL|INT|WEBCHART]
|
||||
#
|
||||
################################################################
|
||||
sub
|
||||
@ -632,16 +653,22 @@ DbLog_Get($@)
|
||||
" <out> is a prefix, - means stdout\n"
|
||||
if(int(@a) < 5);
|
||||
shift @a;
|
||||
my $inf = shift @a;
|
||||
my $outf = shift @a;
|
||||
my $inf = lc(shift @a);
|
||||
my $outf = lc(shift @a);
|
||||
my $from = shift @a;
|
||||
my $to = shift @a; # Now @a contains the list of column_specs
|
||||
my ($internal, @fld);
|
||||
|
||||
if($outf eq "INT") {
|
||||
if($inf eq "-") {
|
||||
$inf = "history";
|
||||
}
|
||||
|
||||
if($outf eq "int") {
|
||||
$outf = "-";
|
||||
$internal = 1;
|
||||
} elsif (uc($outf) eq "WEBCHART") {
|
||||
} elsif($outf eq "array"){
|
||||
|
||||
} elsif(uc($outf) eq "webchart") {
|
||||
# redirect the get request to the chartQuery function
|
||||
return chartQuery($hash, @_);
|
||||
}
|
||||
@ -659,7 +686,8 @@ DbLog_Get($@)
|
||||
$to = $to_datetime{datetime};
|
||||
|
||||
|
||||
my ($retval,$sql_timestamp,$sql_value, $type, $event, $unit) = "";
|
||||
my ($retval,$sql_timestamp, $sql_device, $sql_reading, $sql_value, $type, $event, $unit) = "";
|
||||
my @ReturnArray;
|
||||
my $writeout = 0;
|
||||
my (@min, @max, @sum, @cnt, @lastv, @lastd);
|
||||
my (%tstamp, %lasttstamp, $out_tstamp, $out_value, $minval, $maxval); #fuer delta-h/d Berechnung
|
||||
@ -672,6 +700,8 @@ DbLog_Get($@)
|
||||
$readings[$i][2] = $fld[2]; # Default
|
||||
$readings[$i][3] = $fld[3]; # function
|
||||
$readings[$i][4] = $fld[4]; # regexp
|
||||
|
||||
$readings[$i][1] = "%" if(length($readings[$i][1])==0); #falls Reading nicht gefüllt setze Joker
|
||||
}
|
||||
|
||||
#create new connection for plotfork
|
||||
@ -687,7 +717,7 @@ DbLog_Get($@)
|
||||
$sqlspec{get_timestamp} = "TO_CHAR(TIMESTAMP, 'YYYY-MM-DD HH24:MI:SS')";
|
||||
$sqlspec{from_timestamp} = "TO_TIMESTAMP('$from', 'YYYY-MM-DD HH24:MI:SS')";
|
||||
$sqlspec{to_timestamp} = "TO_TIMESTAMP('$to', 'YYYY-MM-DD HH24:MI:SS')";
|
||||
$sqlspec{reading_clause} = "(DEVICE || '|' || READING)";
|
||||
#$sqlspec{reading_clause} = "(DEVICE || '|' || READING)";
|
||||
} elsif ($hash->{DBMODEL} eq "ORACLE") {
|
||||
$sqlspec{get_timestamp} = "TO_CHAR(TIMESTAMP, 'YYYY-MM-DD HH24:MI:SS')";
|
||||
$sqlspec{from_timestamp} = "TO_TIMESTAMP('$from', 'YYYY-MM-DD HH24:MI:SS')";
|
||||
@ -706,7 +736,7 @@ DbLog_Get($@)
|
||||
$sqlspec{to_timestamp} = "'$to'";
|
||||
}
|
||||
|
||||
if(uc($outf) eq "ALL") {
|
||||
if($outf =~ m/(all|array)/) {
|
||||
$sqlspec{all} = ",TYPE,EVENT,UNIT";
|
||||
} else {
|
||||
$sqlspec{all} = "";
|
||||
@ -724,33 +754,46 @@ DbLog_Get($@)
|
||||
$minval = 999999;
|
||||
$maxval = -999999;
|
||||
|
||||
my $stm= "SELECT
|
||||
$sqlspec{get_timestamp},
|
||||
VALUE
|
||||
$sqlspec{all}
|
||||
FROM history
|
||||
WHERE
|
||||
DEVICE = '".$readings[$i]->[0]."'
|
||||
AND READING = '".$readings[$i]->[1]."'
|
||||
AND TIMESTAMP > $sqlspec{from_timestamp}
|
||||
AND TIMESTAMP < $sqlspec{to_timestamp}
|
||||
ORDER BY TIMESTAMP";
|
||||
my $stm;
|
||||
$stm = "SELECT
|
||||
$sqlspec{get_timestamp},
|
||||
DEVICE,
|
||||
READING,
|
||||
VALUE
|
||||
$sqlspec{all} ";
|
||||
|
||||
Log3 $hash->{NAME}, 5, "Executing $stm";
|
||||
$stm .= "FROM current " if($inf eq "current");
|
||||
$stm .= "FROM history " if($inf eq "history");
|
||||
|
||||
$stm .= "WHERE 1=1 ";
|
||||
|
||||
$stm .= "AND DEVICE = '".$readings[$i]->[0]."' " if ($readings[$i]->[0] !~ m(\%));
|
||||
$stm .= "AND DEVICE LIKE '".$readings[$i]->[0]."' " if(($readings[$i]->[0] !~ m(^\%$)) && ($readings[$i]->[0] =~ m(\%)));
|
||||
|
||||
$stm .= "AND READING = '".$readings[$i]->[1]."' " if ($readings[$i]->[1] !~ m(\%));
|
||||
$stm .= "AND READING LIKE '".$readings[$i]->[1]."' " if(($readings[$i]->[1] !~ m(^%$)) && ($readings[$i]->[1] =~ m(\%)));
|
||||
|
||||
$stm .= "AND TIMESTAMP > $sqlspec{from_timestamp}
|
||||
AND TIMESTAMP < $sqlspec{to_timestamp}
|
||||
ORDER BY TIMESTAMP";
|
||||
|
||||
Log3 $hash->{NAME}, 4, "Processing Statement: $stm";
|
||||
|
||||
my $sth= $dbh->prepare($stm) ||
|
||||
return "Cannot prepare statement $stm: $DBI::errstr";
|
||||
my $rc= $sth->execute() ||
|
||||
return "Cannot execute statement $stm: $DBI::errstr";
|
||||
|
||||
if(uc($outf) eq "ALL") {
|
||||
$sth->bind_columns(undef, \$sql_timestamp, \$sql_value, \$type, \$event, \$unit);
|
||||
|
||||
$retval .= "Timestamp: Device, Type, Event, Reading, Value, Unit\n";
|
||||
$retval .= "=====================================================\n";
|
||||
if($outf =~ m/(all|array)/) {
|
||||
$sth->bind_columns(undef, \$sql_timestamp, \$sql_device, \$sql_reading, \$sql_value, \$type, \$event, \$unit);
|
||||
}
|
||||
else {
|
||||
$sth->bind_columns(undef, \$sql_timestamp, \$sql_value);
|
||||
$sth->bind_columns(undef, \$sql_timestamp, \$sql_value);
|
||||
}
|
||||
|
||||
if ($outf =~ m/(all)/) {
|
||||
$retval .= "Timestamp: Device, Type, Event, Reading, Value, Unit\n";
|
||||
$retval .= "=====================================================\n";
|
||||
}
|
||||
|
||||
while($sth->fetch()) {
|
||||
@ -840,8 +883,13 @@ DbLog_Get($@)
|
||||
|
||||
###################### Ausgabe ###########################
|
||||
if($writeout) {
|
||||
if(uc($outf) eq "ALL") {
|
||||
$retval .= sprintf("%s: %s, %s, %s, %s, %s, %s\n", $out_tstamp, $readings[$i]->[0], $type, $event, $readings[$i]->[1], $out_value, $unit);
|
||||
if ($outf =~ m/(all)/) {
|
||||
# Timestamp: Device, Type, Event, Reading, Value, Unit
|
||||
$retval .= sprintf("%s: %s, %s, %s, %s, %s, %s\n", $out_tstamp, $sql_device, $type, $event, $sql_reading, $out_value, $unit);
|
||||
|
||||
} elsif ($outf =~ m/(array)/) {
|
||||
push(@ReturnArray, {"tstamp" => $out_tstamp, "device" => $sql_device, "type" => $type, "event" => $event, "reading" => $sql_reading, "value" => $out_value, "unit" => $unit});
|
||||
|
||||
} else {
|
||||
$out_tstamp =~ s/\ /_/g; #needed by generating plots
|
||||
$retval .= "$out_tstamp $out_value\n";
|
||||
@ -873,12 +921,17 @@ DbLog_Get($@)
|
||||
$out_value = sprintf("%g", $maxval - $minval);
|
||||
$out_tstamp = DbLog_implode_datetime($lasttstamp{year}, $lasttstamp{month}, $lasttstamp{day}, $lasttstamp{hour}, "30", "00") if($readings[$i]->[3] eq "delta-h");
|
||||
$out_tstamp = DbLog_implode_datetime($lasttstamp{year}, $lasttstamp{month}, $lasttstamp{day}, "00", "00", "00") if($readings[$i]->[3] eq "delta-d");
|
||||
if(uc($outf) eq "ALL") {
|
||||
$retval .= sprintf("%s: %s %s %s %s %s %s\n", $out_tstamp, $readings[$i]->[0], $type, $event, $readings[$i]->[1], $out_value, $unit);
|
||||
} else {
|
||||
$out_tstamp =~ s/\ /_/g; #needed by generating plots
|
||||
$retval .= "$out_tstamp $out_value\n";
|
||||
}
|
||||
|
||||
if($outf =~ m/(all)/) {
|
||||
$retval .= sprintf("%s: %s %s %s %s %s %s\n", $out_tstamp, $sql_device, $type, $event, $sql_reading, $out_value, $unit);
|
||||
|
||||
} elsif ($outf =~ m/(array)/) {
|
||||
push(@ReturnArray, {"tstamp" => $out_tstamp, "device" => $sql_device, "type" => $type, "event" => $event, "reading" => $sql_reading, "value" => $out_value, "unit" => $unit});
|
||||
|
||||
} else {
|
||||
$out_tstamp =~ s/\ /_/g; #needed by generating plots
|
||||
$retval .= "$out_tstamp $out_value\n";
|
||||
}
|
||||
}
|
||||
# DatenTrenner setzen
|
||||
$retval .= "#$readings[$i]->[0]";
|
||||
@ -911,8 +964,13 @@ DbLog_Get($@)
|
||||
if($internal) {
|
||||
$internal_data = \$retval;
|
||||
return undef;
|
||||
|
||||
} elsif($outf =~ m/(array)/) {
|
||||
return @ReturnArray;
|
||||
|
||||
} else {
|
||||
return $retval;
|
||||
}
|
||||
return $retval;
|
||||
}
|
||||
|
||||
################################################################
|
||||
@ -1240,18 +1298,17 @@ sub chartQuery($@) {
|
||||
contains the last event for any given reading and device.
|
||||
The columns have the following meaning:
|
||||
<ol>
|
||||
<li>TIMESTAMP: timestamp of event, e.g. <code>2007-12-30 21:45:22</code></li>
|
||||
<li>DEVICE: device name, e.g. <code>Wetterstation</code></li>
|
||||
<li>TYPE: device type, e.g. <code>KS300</code></li>
|
||||
<li>EVENT: event specification as full string,
|
||||
e.g. <code>humidity: 71 (%)</code></li>
|
||||
<li>READING: name of reading extracted from event,
|
||||
e.g. <code>humidity</code></li>
|
||||
|
||||
<li>TIMESTAMP: timestamp of event, e.g. <code>2007-12-30 21:45:22</code></li>
|
||||
<li>DEVICE: device name, e.g. <code>Wetterstation</code></li>
|
||||
<li>TYPE: device type, e.g. <code>KS300</code></li>
|
||||
<li>EVENT: event specification as full string,
|
||||
e.g. <code>humidity: 71 (%)</code></li>
|
||||
<li>READING: name of reading extracted from event,
|
||||
e.g. <code>humidity</code></li>
|
||||
|
||||
<li>VALUE: actual reading extracted from event,
|
||||
e.g. <code>71</code></li>
|
||||
<li>UNIT: unit extracted from event, e.g. <code>%</code></li>
|
||||
<li>VALUE: actual reading extracted from event,
|
||||
e.g. <code>71</code></li>
|
||||
<li>UNIT: unit extracted from event, e.g. <code>%</code></li>
|
||||
</ol>
|
||||
The content of VALUE is optimized for automated post-processing, e.g.
|
||||
<code>yes</code> is translated to <code>1</code>
|
||||
@ -1284,11 +1341,25 @@ sub chartQuery($@) {
|
||||
|
||||
<ul>
|
||||
<li><in><br>
|
||||
A dummy parameter for FileLog compatibility. Always set to <code>-</code></li>
|
||||
A dummy parameter for FileLog compatibility. Sessing by defaultto <code>-</code><br>
|
||||
<ul>
|
||||
<li>current: reading actual readings from table "current"</li>
|
||||
<li>history: reading history readings from table "history"</li>
|
||||
<li>-: identical to "history"</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><out><br>
|
||||
A dummy parameter for FileLog compatibility. Set it to <code>-</code>
|
||||
to check the output for plot-computing.<br>Set it to the special keyword
|
||||
<code>all</code> to get all columns from Database.</li>
|
||||
A dummy parameter for FileLog compatibility. Setting by default to <code>-</code>
|
||||
to check the output for plot-computing.<br>
|
||||
Set it to the special keyword
|
||||
<code>all</code> to get all columns from Database.
|
||||
<ul>
|
||||
<li>ALL: get all colums from table, including a header</li>
|
||||
<li>Array: get the columns as array of hashes</li>
|
||||
<li>INT: internally used by generating plots</li>
|
||||
<li>-: default</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><from> / <to><br>
|
||||
Used to select the data. Please use the following timeformat or
|
||||
an initial substring of it:<br>
|
||||
@ -1299,9 +1370,9 @@ sub chartQuery($@) {
|
||||
Syntax: <device>:<reading>:<default>:<fn>:<regexp><br>
|
||||
<ul>
|
||||
<li><device><br>
|
||||
The name of the device. Case sensitive</li>
|
||||
The name of the device. Case sensitive. Using a the joker "%" is supported.</li>
|
||||
<li><reading><br>
|
||||
The reading of the given device to select. Case sensitive.
|
||||
The reading of the given device to select. Case sensitive. Using a the joker "%" is supported.
|
||||
</li>
|
||||
<li><default><br>
|
||||
no implemented yet
|
||||
@ -1344,6 +1415,9 @@ sub chartQuery($@) {
|
||||
Examples:
|
||||
<ul>
|
||||
<li><code>get myDbLog - - 2012-11-10 2012-11-20 KS300:temperature</code></li>
|
||||
<li><code>get myDbLog current ALL - - %:temperature</code></li><br>
|
||||
you will get all actual readings "temperature" from all logged devices.
|
||||
Be carful by using "history" as inputfile because a long execution time will be expected!
|
||||
<li><code>get myDbLog - - 2012-11-10_10 2012-11-10_20 KS300:temperature::int1</code><br>
|
||||
like from 10am until 08pm at 10.11.2012</li>
|
||||
<li><code>get myDbLog - all 2012-11-10 2012-11-20 KS300:temperature</code></li>
|
||||
@ -1472,13 +1546,13 @@ sub chartQuery($@) {
|
||||
definiert in <code><configfilename></code>. (Vergleiche
|
||||
Beipspielkonfigurationsdatei in <code>contrib/dblog/db.conf</code>).<br>
|
||||
Die Konfiguration ist in einer sparaten Datei abgelegt um das Datenbankpasswort
|
||||
nicht in Klartext in der FHEM-Haupt-Konfigurationsdatei speichern zu müssen.
|
||||
Ansonsten wäre es mittels des <a href="../docs/commandref.html#list">list</a>
|
||||
nicht in Klartext in der FHEM-Haupt-Konfigurationsdatei speichern zu mössen.
|
||||
Ansonsten wäre es mittels des <a href="../docs/commandref.html#list">list</a>
|
||||
Befehls einfach auslesbar.
|
||||
<br><br>
|
||||
|
||||
Die Perl-Module <code>DBI</code> and <code>DBD::<dbtype></code>
|
||||
müssen installiert werden (use <code>cpan -i <module></code>
|
||||
mössen installiert werden (use <code>cpan -i <module></code>
|
||||
falls die eigene Distribution diese nicht schon mitbringt).
|
||||
<br><br>
|
||||
|
||||
@ -1487,28 +1561,28 @@ sub chartQuery($@) {
|
||||
Ein Beispielcode zum Erstellen einer MySQL/PostGreSQL Datenbak ist in
|
||||
<code>contrib/dblog/<DBType>_create.sql</code> zu finden.
|
||||
Die Datenbank beinhaltet 2 Tabellen: <code>current</code> und
|
||||
<code>history</code>. Die Tabelle <code>current</code> enthält den letzten Stand
|
||||
<code>history</code>. Die Tabelle <code>current</code> enthält den letzten Stand
|
||||
pro Device und Reading. In der Tabelle <code>history</code> sind alle
|
||||
Events historisch gespeichert.
|
||||
|
||||
Die Tabellenspalten haben folgende Bedeutung:
|
||||
<ol>
|
||||
<li>TIMESTAMP: Zeitpunkt des Events, z.B. <code>2007-12-30 21:45:22</code></li>
|
||||
<li>DEVICE: name des Devices, z.B. <code>Wetterstation</code></li>
|
||||
<li>TYPE: Type des Devices, z.B. <code>KS300</code></li>
|
||||
<li>EVENT: das auftretende Event als volle Zeichenkette
|
||||
z.B. <code>humidity: 71 (%)</code></li>
|
||||
<li>READING: Name des Readings, ermittelt aus dem Event,
|
||||
z.B. <code>humidity</code></li>
|
||||
<li>TIMESTAMP: Zeitpunkt des Events, z.B. <code>2007-12-30 21:45:22</code></li>
|
||||
<li>DEVICE: name des Devices, z.B. <code>Wetterstation</code></li>
|
||||
<li>TYPE: Type des Devices, z.B. <code>KS300</code></li>
|
||||
<li>EVENT: das auftretende Event als volle Zeichenkette
|
||||
z.B. <code>humidity: 71 (%)</code></li>
|
||||
<li>READING: Name des Readings, ermittelt aus dem Event,
|
||||
z.B. <code>humidity</code></li>
|
||||
|
||||
<li>VALUE: aktueller Wert des Readings, ermittelt aus dem Event,
|
||||
z.B. <code>71</code></li>
|
||||
<li>UNIT: Einheit, ermittelt aus dem Event, z.B. <code>%</code></li>
|
||||
<li>VALUE: aktueller Wert des Readings, ermittelt aus dem Event,
|
||||
z.B. <code>71</code></li>
|
||||
<li>UNIT: Einheit, ermittelt aus dem Event, z.B. <code>%</code></li>
|
||||
</ol>
|
||||
Der Wert des Rreadings ist optimiert für eine automatisierte Nachverarbeitung
|
||||
Der Wert des Rreadings ist optimiert för eine automatisierte Nachverarbeitung
|
||||
z.B. <code>yes</code> ist transformiert nach <code>1</code>
|
||||
<br><br>
|
||||
Die gespeicherten Werte können mittels GET Funktion angezeigt werden:
|
||||
Die gespeicherten Werte können mittels GET Funktion angezeigt werden:
|
||||
<ul>
|
||||
<code>get myDbLog - - 2012-11-10 2012-11-10 KS300:temperature</code>
|
||||
</ul>
|
||||
@ -1516,7 +1590,6 @@ sub chartQuery($@) {
|
||||
<b>Beispiel:</b>
|
||||
<ul>
|
||||
<code>Speichert alles in der Datenbank</code><br>
|
||||
|
||||
<code>define myDbLog DbLog /etc/fhem/db.conf .*:.*</code>
|
||||
</ul>
|
||||
</ul>
|
||||
@ -1531,37 +1604,49 @@ sub chartQuery($@) {
|
||||
<code>get <name> <infile> <outfile> <from>
|
||||
<to> <column_spec> </code>
|
||||
<br><br>
|
||||
Ließt Daten aus der Datenbank. Wird durch die Frontends benutzt um Plots
|
||||
zu generieren ohne selbst auf die Datenank zugreifen zu müssen.
|
||||
Liesst Daten aus der Datenbank. Wird durch die Frontends benutzt um Plots
|
||||
zu generieren ohne selbst auf die Datenank zugreifen zu mössen.
|
||||
<br>
|
||||
|
||||
<ul>
|
||||
<li><in><br>
|
||||
Ein Dummy Parameter um eine Kompatibilität zum Filelog herzustellen.
|
||||
Dieser Parameter ist immer auf <code>-</code> zu setzen.
|
||||
Ein Parameter um eine Kompatibilität zum Filelog herzustellen.
|
||||
Dieser Parameter ist per default immer auf <code>-</code> zu setzen.<br>
|
||||
Folgende Ausprägungen sind zugelassen:<br>
|
||||
<ul>
|
||||
<li>current: die aktuellen Werte aus der Tabelle "current" werden gelesen.</li>
|
||||
<li>history: die historischen Werte aus der Tabelle "history" werden gelesen.</li>
|
||||
<li>-: identisch wie "history"</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><out><br>
|
||||
Ein Dummy Parameter um eine Kompatibilität zum Filelog herzustellen.
|
||||
Dieser Parameter ist immer auf <code>-</code> zu setzen um die
|
||||
Ermittlung der Daten aus der Datenbank für die Plotgenerierung zu prüfen.<br>
|
||||
Durchd ie Angabe des Schlüsselworts <code>all</code> werden alle
|
||||
Spalten der Datenbank ausgegeben.
|
||||
</li>
|
||||
Ein Parameter um eine Kompatibilität zum Filelog herzustellen.
|
||||
Dieser Parameter ist per default immer auf <code>-</code> zu setzen um die
|
||||
Ermittlung der Daten aus der Datenbank för die Plotgenerierung zu pröfen.<br>
|
||||
Folgende Ausprägungen sind zugelassen:<br>
|
||||
<ul>
|
||||
<li>ALL: Es werden alle Spalten der Datenbank ausgegeben. Inclusive einer Überschrift.</li>
|
||||
<li>Array: Es werden alle Spalten der Datenbank als Hash ausgegeben. Alle Datensätze als Array zusammengefasst.</li>
|
||||
<li>INT: intern zur Plotgenerierung verwendet</li>
|
||||
<li>-: default</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><from> / <to><br>
|
||||
Wird benutzt um den Zeitraum der Daten einzugrenzen. Es ist das folgende
|
||||
Zeitformat oder ein Teilstring davon zu benutzen:<br>
|
||||
<ul><code>YYYY-MM-DD_HH24:MI:SS</code></ul></li>
|
||||
<li><column_spec><br>
|
||||
Für jede column_spec Gruppe wird ein Datenset zurückgegeben welches
|
||||
durch einen Kommentar getrennt wird. Dieser Kommentar repräsentiert
|
||||
För jede column_spec Gruppe wird ein Datenset zuröckgegeben welches
|
||||
durch einen Kommentar getrennt wird. Dieser Kommentar repräsentiert
|
||||
die column_spec.<br>
|
||||
Syntax: <device>:<reading>:<default>:<fn>:<regexp><br>
|
||||
<ul>
|
||||
<li><device><br>
|
||||
Der Name des Devices. Achtung: Groß/Kleinschreibung beachten!</li>
|
||||
Der Name des Devices. Achtung: Gross/Kleinschreibung beachten!<br>
|
||||
Es kann ein % als Jokerzeichen angegeben werden.</li>
|
||||
<li><reading><br>
|
||||
Das REading des angegebenen Devices zur Datenselektion.
|
||||
Achtung: Groß/Kleinschreibung beachten!
|
||||
Das Reading des angegebenen Devices zur Datenselektion.<br>
|
||||
Es kann ein % als Jokerzeichen angegeben werden.<br>
|
||||
Achtung: Gross/Kleinschreibung beachten!
|
||||
</li>
|
||||
<li><default><br>
|
||||
Zur Zeit noch nicht implementiert.
|
||||
@ -1571,17 +1656,17 @@ sub chartQuery($@) {
|
||||
<ul>
|
||||
<li>int<br>
|
||||
Ermittelt den Zahlenwert ab dem Anfang der Zeichenkette aus der
|
||||
Spalte "VALUE". Benutzt z.B. für Ausprägungen wie 10%.
|
||||
Spalte "VALUE". Benutzt z.B. för Ausprägungen wie 10%.
|
||||
</li>
|
||||
<li>int<digit><br>
|
||||
Ermittelt den Zahlenwert ab dem Anfang der Zeichenkette aus der
|
||||
Spalte "VALUE", inclusive negativen Vorzeichen und Dezimaltrenner.
|
||||
Benutzt z.B. für Ausprägungen wie -5.7°C.
|
||||
Benutzt z.B. för Ausprägungen wie -5.7°C.
|
||||
</li>
|
||||
<li>delta-h / delta-d<br>
|
||||
Ermittelt die relative Veränderung eines Zahlenwertes pro Stunde
|
||||
oder pro Tag. Wird benutzt z.B. für Spalten die einen
|
||||
hochlaufenden Zähler enthalten wie im Falle für ein KS300 Regenzähler
|
||||
Ermittelt die relative Veränderung eines Zahlenwertes pro Stunde
|
||||
oder pro Tag. Wird benutzt z.B. för Spalten die einen
|
||||
hochlaufenden Zähler enthalten wie im Falle för ein KS300 Regenzähler
|
||||
oder dem 1-wire Modul OWCOUNT.
|
||||
</li>
|
||||
<li>delta-ts<br>
|
||||
@ -1590,19 +1675,19 @@ sub chartQuery($@) {
|
||||
</li>
|
||||
</ul></li>
|
||||
<li><regexp><br>
|
||||
Diese Zeichenkette wird als Perl Befehl ausgewertet. Die regexp wird vor dem angegebenen <fn> Parameter ausgeführt.
|
||||
Diese Zeichenkette wird als Perl Befehl ausgewertet. Die regexp wird vor dem angegebenen <fn> Parameter ausgeföhrt.
|
||||
<br>
|
||||
Bitte zur Beachtung: Diese Zeichenkette darf keine Leerzeichen
|
||||
enthalten da diese sonst als <column_spec> Trennung
|
||||
interpretiert werden und alles nach dem Leerzeichen als neue
|
||||
<column_spec> gesehen wird.<br>
|
||||
<b>Schlüsselwörter</b>
|
||||
<li>$val ist der aktuelle Wert die die Datenbank für ein Device/Reading ausgibt.</li>
|
||||
<b>Schlösselwörter</b>
|
||||
<li>$val ist der aktuelle Wert die die Datenbank för ein Device/Reading ausgibt.</li>
|
||||
<li>$ts ist der aktuelle Timestamp des Logeintrages.</li>
|
||||
<li>Wird als $val das Schlüsselwort "hide" zurückgegeben, so wird dieser Logeintrag nicht
|
||||
ausgegeben, trotzdem aber für die Zeitraumberechnung verwendet.</li>
|
||||
<li>Wird als $val das Schlüsselwort "ignore" zurückgegeben, so wird dieser Logeintrag
|
||||
nicht für eine Folgeberechnung verwendet.</li>
|
||||
<li>Wird als $val das Schlösselwort "hide" zuröckgegeben, so wird dieser Logeintrag nicht
|
||||
ausgegeben, trotzdem aber för die Zeitraumberechnung verwendet.</li>
|
||||
<li>Wird als $val das Schlösselwort "ignore" zuröckgegeben, so wird dieser Logeintrag
|
||||
nicht för eine Folgeberechnung verwendet.</li>
|
||||
</li>
|
||||
</ul></li>
|
||||
</ul>
|
||||
@ -1610,39 +1695,42 @@ sub chartQuery($@) {
|
||||
<b>Beispiele:</b>
|
||||
<ul>
|
||||
<li><code>get myDbLog - - 2012-11-10 2012-11-20 KS300:temperature</code></li>
|
||||
<li><code>get myDbLog current ALL - - %:temperature</code></li><br>
|
||||
Damit erhält man alle aktuellen Readings "temperature" von allen in der DB geloggten Devices.
|
||||
Achtung: bei Nutzung von Jokerzeichen auf die historyTabelle kann man sein FHEM aufgrund langer Laufzeit lahmlegen!
|
||||
<li><code>get myDbLog - - 2012-11-10_10 2012-11-10_20 KS300:temperature::int1</code><br>
|
||||
gibt Daten aus von 10Uhr bis 20Uhr am 10.11.2012</li>
|
||||
<li><code>get myDbLog - all 2012-11-10 2012-11-20 KS300:temperature</code></li>
|
||||
<li><code>get myDbLog - - 2012-11-10 2012-11-20 KS300:temperature KS300:rain::delta-h KS300:rain::delta-d</code></li>
|
||||
<li><code>get myDbLog - - 2012-11-10 2012-11-20 MyFS20:data:::$val=~s/(on|off).*/$1eq"on"?1:0/eg</code><br>
|
||||
gibt 1 zurück für alle Ausprägungen von on* (on|on-for-timer etc) und 0 für alle off*</li>
|
||||
gibt 1 zuröck för alle Ausprägungen von on* (on|on-for-timer etc) und 0 för alle off*</li>
|
||||
<li><code>get myDbLog - - 2012-11-10 2012-11-20 Bodenfeuchte:data:::$val=~s/.*B:\s([-\.\d]+).*/$1/eg</code><br>
|
||||
Beispiel von OWAD: Ein Wert wie z.B.: <code>"A: 49.527 % B: 66.647 % C: 9.797 % D: 0.097 V"</code><br>
|
||||
und die Ausgabe ist für das Reading B folgende: <code>2012-11-20_10:23:54 66.647</code></li>
|
||||
und die Ausgabe ist för das Reading B folgende: <code>2012-11-20_10:23:54 66.647</code></li>
|
||||
<li><code>get DbLog - - 2013-05-26 2013-05-28 Pumpe:data::delta-ts:$val=~s/on/hide/</code><br>
|
||||
Realisierung eines Betriebsstundenzählers.Durch delta-ts wird die Zeit in Sek zwischen den Log-
|
||||
einträgen ermittelt. Die Zeiten werden bei den on-Meldungen nicht ausgegeben welche einer Abschaltzeit
|
||||
entsprechen würden.</li>
|
||||
Realisierung eines Betriebsstundenzählers.Durch delta-ts wird die Zeit in Sek zwischen den Log-
|
||||
einträgen ermittelt. Die Zeiten werden bei den on-Meldungen nicht ausgegeben welche einer Abschaltzeit
|
||||
entsprechen wörden.</li>
|
||||
</ul>
|
||||
<br><br>
|
||||
</ul>
|
||||
|
||||
<b>Get</b> für die Nutzung von webcharts
|
||||
<b>Get</b> för die Nutzung von webcharts
|
||||
<ul>
|
||||
<code>get <name> <infile> <outfile> <from>
|
||||
<to> <device> <querytype> <xaxis> <yaxis> <savename> </code>
|
||||
<br><br>
|
||||
Liest Daten aus der Datenbank aus und gibt diese in JSON formatiert aus. Wird für das Charting Frontend genutzt
|
||||
Liest Daten aus der Datenbank aus und gibt diese in JSON formatiert aus. Wird för das Charting Frontend genutzt
|
||||
<br>
|
||||
|
||||
<ul>
|
||||
<li><name><br>
|
||||
Der Name des definierten DbLogs, so wie er in der fhem.cfg angegeben wurde.</li>
|
||||
<li><in><br>
|
||||
Ein Dummy Parameter um eine Kompatibilität zum Filelog herzustellen.
|
||||
Ein Dummy Parameter um eine Kompatibilität zum Filelog herzustellen.
|
||||
Dieser Parameter ist immer auf <code>-</code> zu setzen.</li>
|
||||
<li><out><br>
|
||||
Ein Dummy Parameter um eine Kompatibilität zum Filelog herzustellen.
|
||||
Ein Dummy Parameter um eine Kompatibilität zum Filelog herzustellen.
|
||||
Dieser Parameter ist auf <code>webchart</code> zu setzen um die Charting Get Funktion zu nutzen.
|
||||
</li>
|
||||
<li><from> / <to><br>
|
||||
@ -1652,32 +1740,32 @@ sub chartQuery($@) {
|
||||
<li><device><br>
|
||||
Ein String, der das abzufragende Device darstellt.</li>
|
||||
<li><querytype><br>
|
||||
Ein String, der die zu verwendende Abfragemethode darstellt. Zur Zeit unterstützte Werte sind: <br>
|
||||
<code>getreadings</code> um für ein bestimmtes device alle Readings zu erhalten<br>
|
||||
<code>getdevices</code> um alle verfügbaren devices zu erhalten<br>
|
||||
<code>timerange</code> um Chart-Daten abzufragen. Es werden die Parameter 'xaxis', 'yaxis', 'device', 'to' und 'from' benötigt<br>
|
||||
<code>savechart</code> um einen Chart unter Angabe eines 'savename' und seiner zugehörigen Konfiguration abzuspeichern<br>
|
||||
<code>deletechart</code> um einen zuvor gespeicherten Chart unter Angabe einer id zu löschen<br>
|
||||
Ein String, der die zu verwendende Abfragemethode darstellt. Zur Zeit unterstötzte Werte sind: <br>
|
||||
<code>getreadings</code> um för ein bestimmtes device alle Readings zu erhalten<br>
|
||||
<code>getdevices</code> um alle verfögbaren devices zu erhalten<br>
|
||||
<code>timerange</code> um Chart-Daten abzufragen. Es werden die Parameter 'xaxis', 'yaxis', 'device', 'to' und 'from' benötigt<br>
|
||||
<code>savechart</code> um einen Chart unter Angabe eines 'savename' und seiner zugehörigen Konfiguration abzuspeichern<br>
|
||||
<code>deletechart</code> um einen zuvor gespeicherten Chart unter Angabe einer id zu löschen<br>
|
||||
<code>getcharts</code> um eine Liste aller gespeicherten Charts zu bekommen.<br>
|
||||
<code>getTableData</code> um Daten aus der Datenbank abzufragen und in einer Tabelle darzustellen. Benötigt paging Parameter wie start und limit.<br>
|
||||
<code>hourstats</code> um Statistiken für einen Wert (yaxis) für eine Stunde abzufragen.<br>
|
||||
<code>daystats</code> um Statistiken für einen Wert (yaxis) für einen Tag abzufragen.<br>
|
||||
<code>weekstats</code> um Statistiken für einen Wert (yaxis) für eine Woche abzufragen.<br>
|
||||
<code>monthstats</code> um Statistiken für einen Wert (yaxis) für einen Monat abzufragen.<br>
|
||||
<code>yearstats</code> um Statistiken für einen Wert (yaxis) für ein Jahr abzufragen.<br>
|
||||
<code>getTableData</code> um Daten aus der Datenbank abzufragen und in einer Tabelle darzustellen. Benötigt paging Parameter wie start und limit.<br>
|
||||
<code>hourstats</code> um Statistiken för einen Wert (yaxis) för eine Stunde abzufragen.<br>
|
||||
<code>daystats</code> um Statistiken för einen Wert (yaxis) för einen Tag abzufragen.<br>
|
||||
<code>weekstats</code> um Statistiken för einen Wert (yaxis) för eine Woche abzufragen.<br>
|
||||
<code>monthstats</code> um Statistiken för einen Wert (yaxis) för einen Monat abzufragen.<br>
|
||||
<code>yearstats</code> um Statistiken för einen Wert (yaxis) för ein Jahr abzufragen.<br>
|
||||
</li>
|
||||
<li><xaxis><br>
|
||||
Ein String, der die X-Achse repräsentiert</li>
|
||||
Ein String, der die X-Achse repräsentiert</li>
|
||||
<li><yaxis><br>
|
||||
Ein String, der die Y-Achse repräsentiert</li>
|
||||
Ein String, der die Y-Achse repräsentiert</li>
|
||||
<li><savename><br>
|
||||
Ein String, unter dem ein Chart in der Datenbank gespeichert werden soll</li>
|
||||
<li><chartconfig><br>
|
||||
Ein jsonstring der den zu speichernden Chart repräsentiert</li>
|
||||
Ein jsonstring der den zu speichernden Chart repräsentiert</li>
|
||||
<li><pagingstart><br>
|
||||
Ein Integer um den Startwert für die Abfrage 'getTableData' festzulegen</li>
|
||||
Ein Integer um den Startwert för die Abfrage 'getTableData' festzulegen</li>
|
||||
<li><paginglimit><br>
|
||||
Ein Integer um den Limitwert für die Abfrage 'getTableData' festzulegen</li>
|
||||
Ein Integer um den Limitwert för die Abfrage 'getTableData' festzulegen</li>
|
||||
</ul>
|
||||
<br><br>
|
||||
Beispiele:
|
||||
@ -1685,16 +1773,16 @@ sub chartQuery($@) {
|
||||
<li><code>get logdb - webchart "" "" "" getcharts</code><br>
|
||||
Liefert alle gespeicherten Charts aus der Datenbank</li>
|
||||
<li><code>get logdb - webchart "" "" "" getdevices</code><br>
|
||||
Liefert alle verfügbaren Devices aus der Datenbank</li>
|
||||
Liefert alle verfögbaren Devices aus der Datenbank</li>
|
||||
<li><code>get logdb - webchart "" "" ESA2000_LED_011e getreadings</code><br>
|
||||
Liefert alle verfügbaren Readings aus der Datenbank unter Angabe eines Gerätes</li>
|
||||
Liefert alle verfögbaren Readings aus der Datenbank unter Angabe eines Gerätes</li>
|
||||
<li><code>get logdb - webchart 2013-02-11_00:00:00 2013-02-12_00:00:00 ESA2000_LED_011e timerange TIMESTAMP day_kwh</code><br>
|
||||
Liefert Chart-Daten, die auf folgenden Parametern basieren: 'xaxis', 'yaxis', 'device', 'to' und 'from'<br>
|
||||
Die Ausgabe erfolgt als JSON, z.B.: <code>[{'TIMESTAMP':'2013-02-11 00:10:10','VALUE':'0.22431388090756'},{'TIMESTAMP'.....}]</code></li>
|
||||
<li><code>get logdb - webchart 2013-02-11_00:00:00 2013-02-12_00:00:00 ESA2000_LED_011e savechart TIMESTAMP day_kwh tageskwh</code><br>
|
||||
Speichert einen Chart unter Angabe eines 'savename' und seiner zugehörigen Konfiguration</li>
|
||||
Speichert einen Chart unter Angabe eines 'savename' und seiner zugehörigen Konfiguration</li>
|
||||
<li><code>get logdb - webchart "" "" "" deletechart "" "" 7</code><br>
|
||||
Löscht einen zuvor gespeicherten Chart unter Angabe einer id</li>
|
||||
Löscht einen zuvor gespeicherten Chart unter Angabe einer id</li>
|
||||
</ul>
|
||||
<br><br>
|
||||
</ul>
|
||||
@ -1709,11 +1797,11 @@ sub chartQuery($@) {
|
||||
</ul>
|
||||
<br>
|
||||
Wenn DbLog genutzt wird, wird in alle Devices das Attribut <i>DbLogExclude</i>
|
||||
propagiert. Der Wert des Attributes wird als Regexp ausgewertet und schließt die
|
||||
propagiert. Der Wert des Attributes wird als Regexp ausgewertet und schliesst die
|
||||
damit matchenden Readings von einem Logging aus. Einzelne Regexp werden durch
|
||||
Kommata getrennt. Ist MinIntervall angegeben, so wird der Logeintrag nur
|
||||
dann nicht geloggt, wenn das Intervall noch nicht erreicht und der Wert des
|
||||
Readings sich nicht verändert hat.
|
||||
Readings sich nicht verändert hat.
|
||||
<br>
|
||||
<b>Beispiele</b>
|
||||
<ul>
|
||||
|
@ -62,6 +62,8 @@ sub Text2Speech_Initialize($)
|
||||
" TTS_UseMP3Wrap:0,1".
|
||||
" TTS_MplayerCall".
|
||||
" TTS_SentenceAppendix".
|
||||
" TTS_FileMapping".
|
||||
" TTS_FileTemplateDir".
|
||||
" ".$readingFnAttributes;
|
||||
}
|
||||
|
||||
@ -145,6 +147,10 @@ sub Text2Speech_Attr(@) {
|
||||
my $hash = $defs{$a[1]};
|
||||
my $value = $a[3];
|
||||
|
||||
my $TTS_FileTemplateDir = AttrVal($hash->{NAME}, "TTS_FileTemplateDir", "templates");
|
||||
my $TTS_CacheFileDir = AttrVal($hash->{NAME}, "TTS_CacheFileDir", "cache");
|
||||
my $TTS_FileMapping = AttrVal($hash->{NAME}, "TTS_FileMapping", ""); # zb, silence:silence.mp3 ring:myringtone.mp3;
|
||||
|
||||
if($a[2] eq "TTS_Delemiter" && $a[0] ne "del") {
|
||||
return "wrong delemiter syntax: [+-]a[lfn]. \n".
|
||||
" Example 1: +an~\n".
|
||||
@ -166,8 +172,23 @@ sub Text2Speech_Attr(@) {
|
||||
return "This Attribute is only available in direct mode" if($hash->{MODE} ne "DIRECT");
|
||||
return "Attribute TTS_UseMP3Wrap is required!" unless(AttrVal($hash->{NAME}, "TTS_UseMP3Wrap", undef));
|
||||
|
||||
my $file = AttrVal($hash->{NAME}, "TTS_CacheFileDir", "cache") ."/". $value;
|
||||
my $file = $TTS_CacheFileDir ."/". $value;
|
||||
return "File <".$file."> does not exists in CacheFileDir" if(! -e $file);
|
||||
|
||||
} elsif ($a[2] eq "TTS_FileTemplateDir") {
|
||||
unless(-e ($TTS_CacheFileDir ."/". $value) or mkdir ($TTS_CacheFileDir ."/". $value)) {
|
||||
#Verzeichnis anlegen gescheitert
|
||||
return "Could not create directory: <$value>";
|
||||
}
|
||||
|
||||
} elsif ($a[2] eq "TTS_FileMapping") {
|
||||
#ueberpruefen, ob mp3 Template existiert
|
||||
my @FileTpl = split(" ", $TTS_FileMapping);
|
||||
for(my $j=0; $j<(@FileTpl); $j++) {
|
||||
my @FileTplPc = split(/:/, $FileTpl[$j]);
|
||||
return "file does not exist: <".$TTS_CacheFileDir ."/". $TTS_FileTemplateDir ."/". $FileTplPc[1] .">"
|
||||
unless (-e $TTS_CacheFileDir ."/". $TTS_FileTemplateDir ."/". $FileTplPc[1]);
|
||||
}
|
||||
}
|
||||
|
||||
if($a[0] eq "set" && $a[2] eq "disable") {
|
||||
@ -319,6 +340,8 @@ sub Text2Speech_PrepareSpeech($$) {
|
||||
|
||||
my $TTS_Ressource = AttrVal($hash->{NAME}, "TTS_Ressource", "Google");
|
||||
my $TTS_Delemiter = AttrVal($hash->{NAME}, "TTS_Delemiter", undef);
|
||||
my $TTS_FileTpl = AttrVal($hash->{NAME}, "TTS_FileMapping", ""); # zb, silence:silence.mp3 ring:myringtone.mp3; im Text: mein Klingelton :ring: ist laut.
|
||||
my $TTS_FileTemplateDir = AttrVal($hash->{NAME}, "TTS_FileTemplateDir", "templates");
|
||||
|
||||
my $TTS_ForceSplit = 0;
|
||||
my $TTS_AddDelemiter;
|
||||
@ -351,12 +374,30 @@ sub Text2Speech_PrepareSpeech($$) {
|
||||
@text = $hash->{helper}{Text2Speech} if($hash->{helper}{Text2Speech}[0]);
|
||||
push(@text, $t);
|
||||
|
||||
my @FileTpl = split(" ", $TTS_FileTpl);
|
||||
my @FileTplPc;
|
||||
for(my $i=0; $i<(@FileTpl); $i++) {
|
||||
#splitte bei jedem Template auf
|
||||
@FileTplPc = split(/:/, $FileTpl[$i]);
|
||||
@text = Text2Speech_SplitString(\@text, 100, ":".$FileTplPc[0].":", 1, "as"); # splitte bei bspw: :ring:
|
||||
}
|
||||
|
||||
@text = Text2Speech_SplitString(\@text, 100, $TTS_Delemiter, $TTS_ForceSplit, $TTS_AddDelemiter);
|
||||
@text = Text2Speech_SplitString(\@text, 100, "(?<=[\\.!?])\\s*", 0, "");
|
||||
@text = Text2Speech_SplitString(\@text, 100, ",", 0, "al");
|
||||
@text = Text2Speech_SplitString(\@text, 100, ";", 0, "al");
|
||||
@text = Text2Speech_SplitString(\@text, 100, "und", 0, "af");
|
||||
|
||||
for(my $i=0; $i<(@text); $i++) {
|
||||
for(my $j=0; $j<(@FileTpl); $j++) {
|
||||
# entferne führende und abschließende Leerzeichen aus jedem Textbaustein
|
||||
$text[$i] =~ s/^\s+|\s+$//g;
|
||||
# ersetze die FileTemplates
|
||||
@FileTplPc = split(/:/, $FileTpl[$j]);
|
||||
$text[$i] = $TTS_FileTemplateDir ."/". $FileTplPc[1] if($text[$i] eq ":".$FileTplPc[0].":")
|
||||
}
|
||||
}
|
||||
|
||||
@{$hash->{helper}{Text2Speech}} = @text;
|
||||
|
||||
} else {
|
||||
@ -370,7 +411,7 @@ sub Text2Speech_PrepareSpeech($$) {
|
||||
# param3: string: Delemiter
|
||||
# param4: int : 1 -> es wird am Delemiter gesplittet
|
||||
# 0 -> es wird nur gesplittet, wenn Stringlänge länger als MaxChar
|
||||
# param5: string: Add Delemiter to String? [pre|past|<empty>]
|
||||
# param5: string: Add Delemiter to String? [al|af|as|<empty>] (AddLast/AddFirst/AddSingle)
|
||||
#
|
||||
# Splittet die Texte aus $hash->{helper}->{Text2Speech} anhand des
|
||||
# Delemiters, wenn die Stringlänge MaxChars übersteigt.
|
||||
@ -395,7 +436,7 @@ sub Text2Speech_SplitString(@$$$$){
|
||||
for(my $j=0; $j<(@b); $j++) {
|
||||
$b[$j] = $b[$j] . $Delemiter if($AddDelemiter eq "al"); # Am Satzende wieder hinzufügen.
|
||||
$b[$j+1] = $Delemiter . $b[$j+1] if(($AddDelemiter eq "af") && ($b[$j+1])); # Am Satzanfang des nächsten Satzes wieder hinzufügen.
|
||||
|
||||
push(@newText, $Delemiter) if($AddDelemiter eq "as" && $j>0); # AddSingle: füge Delemiter als EinzelSatz hinzu. Zb. bei FileTemplates
|
||||
push(@newText, $b[$j]);
|
||||
}
|
||||
}
|
||||
@ -434,6 +475,33 @@ sub Text2Speech_BuildMplayerCmdString($$) {
|
||||
return $cmd;
|
||||
}
|
||||
|
||||
#####################################
|
||||
# param1: hash : Hash
|
||||
# param2: string: Dateiname
|
||||
# param2: string: Text
|
||||
#
|
||||
# Holt den Text aus dem Google Translator als MP3Datei
|
||||
#####################################
|
||||
sub Text2Speech_Download($$$) {
|
||||
my ($hash, $file, $text) = @_;
|
||||
|
||||
my $HttpResponse;
|
||||
my $fh;
|
||||
|
||||
Log3 $hash->{NAME}, 4, "Text2Speech: Hole URL: ". "http://" . $ttsHost . $ttsPath . uri_escape($text);
|
||||
$HttpResponse = GetHttpFile($ttsHost, $ttsPath . uri_escape($text));
|
||||
|
||||
$fh = new IO::File ">$file";
|
||||
if(!defined($fh)) {
|
||||
Log3 $hash->{NAME}, 2, "Text2Speech: mp3 Datei <$file> konnte nicht angelegt werden.";
|
||||
return undef;
|
||||
}
|
||||
|
||||
$fh->print($HttpResponse);
|
||||
Log3 $hash->{NAME}, 4, "Text2Speech: Schreibe mp3 in die Datei $file mit ".length($HttpResponse)." Bytes";
|
||||
close($fh);
|
||||
}
|
||||
|
||||
#####################################
|
||||
sub Text2Speech_DoIt($) {
|
||||
my ($hash) = @_;
|
||||
@ -445,7 +513,6 @@ sub Text2Speech_DoIt($) {
|
||||
|
||||
if($TTS_Ressource eq "Google") {
|
||||
|
||||
my $HttpResponse;
|
||||
my $filename;
|
||||
my $file;
|
||||
|
||||
@ -459,30 +526,35 @@ sub Text2Speech_DoIt($) {
|
||||
if(AttrVal($hash->{NAME}, "TTS_UseMP3Wrap", 0)) {
|
||||
# benutze das Tool MP3Wrap um bereits einzelne vorhandene Sprachdateien
|
||||
# zusammenzuführen. Ziel: sauberer Sprachfluss
|
||||
my @Mp3WrapArray;
|
||||
my $Mp3WrapText = "";
|
||||
my @Mp3WrapFiles;
|
||||
my @Mp3WrapText;
|
||||
my $TTS_SentenceAppendix = AttrVal($hash->{NAME}, "TTS_SentenceAppendix", undef); #muss eine mp3-Datei sein, ohne Pfadangabe
|
||||
undef($TTS_SentenceAppendix) if($TTS_SentenceAppendix && (! -e $TTS_CacheFileDir ."/".$TTS_SentenceAppendix));
|
||||
my $TTS_FileTemplateDir = AttrVal($hash->{NAME}, "TTS_FileTemplateDir", "templates");
|
||||
|
||||
$TTS_SentenceAppendix = $TTS_CacheFileDir ."/". $TTS_FileTemplateDir ."/". $TTS_SentenceAppendix if($TTS_SentenceAppendix);
|
||||
undef($TTS_SentenceAppendix) if($TTS_SentenceAppendix && (! -e $TTS_SentenceAppendix));
|
||||
|
||||
#Abspielliste erstellen
|
||||
foreach my $t (@{$hash->{helper}{Text2Speech}}) {
|
||||
$filename = md5_hex($t) . ".mp3";
|
||||
if(-e $TTS_CacheFileDir."/".$t) { $filename = $t;} else {$filename = md5_hex($t) . ".mp3";} # falls eine bestimmte mp3-Datei gespielt werden soll
|
||||
$file = $TTS_CacheFileDir."/".$filename;
|
||||
if(-e $file) {
|
||||
push(@Mp3WrapArray, $file);
|
||||
$Mp3WrapText .= $t;
|
||||
push(@Mp3WrapFiles, $file);
|
||||
push(@Mp3WrapText, $t);
|
||||
#Text2Speech_WriteStats($hash, 0, $file, $t);
|
||||
} else {last;}
|
||||
}
|
||||
|
||||
push(@Mp3WrapArray, $TTS_CacheFileDir ."/".$TTS_SentenceAppendix) if($TTS_SentenceAppendix);
|
||||
push(@Mp3WrapFiles, $TTS_SentenceAppendix) if($TTS_SentenceAppendix);
|
||||
|
||||
if(scalar(@Mp3WrapArray) >= 2) {
|
||||
Log3 $hash->{NAME}, 4, "Text2Speech: Bearbeite per MP3Wrap jetzt den Text: ". $Mp3WrapText;
|
||||
if(scalar(@Mp3WrapFiles) >= 2) {
|
||||
Log3 $hash->{NAME}, 4, "Text2Speech: Bearbeite per MP3Wrap jetzt den Text: ". join(" ", @Mp3WrapText);
|
||||
|
||||
my $Mp3WrapPrefix = md5_hex(join("|", @Mp3WrapArray));
|
||||
my $Mp3WrapPrefix = md5_hex(join("|", @Mp3WrapFiles));
|
||||
my $Mp3WrapFile = $TTS_CacheFileDir ."/". $Mp3WrapPrefix . "_MP3WRAP.mp3";
|
||||
|
||||
if(! -e $Mp3WrapFile) {
|
||||
$cmd = "mp3wrap " .$TTS_CacheFileDir. "/" .$Mp3WrapPrefix. ".mp3 " .join(" ", @Mp3WrapArray);
|
||||
$cmd = "mp3wrap " .$TTS_CacheFileDir. "/" .$Mp3WrapPrefix. ".mp3 " .join(" ", @Mp3WrapFiles);
|
||||
$cmd .= " >/dev/null" if($verbose < 5);;
|
||||
|
||||
Log3 $hash->{NAME}, 4, "Text2Speech: " .$cmd;
|
||||
@ -492,36 +564,29 @@ sub Text2Speech_DoIt($) {
|
||||
$cmd = Text2Speech_BuildMplayerCmdString($hash, $Mp3WrapFile);
|
||||
Log3 $hash->{NAME}, 4, "Text2Speech:" .$cmd;
|
||||
system($cmd);
|
||||
#Text2Speech_WriteStats($hash, 1, $Mp3WrapFile, join(" ", @Mp3WrapText));
|
||||
} else {
|
||||
Log3 $hash->{NAME}, 2, "Text2Speech: Mp3Wrap Datei konnte nicht angelegt werden.";
|
||||
}
|
||||
|
||||
return $hash->{NAME} . "|". scalar(@Mp3WrapArray);
|
||||
return $hash->{NAME} ."|".
|
||||
($TTS_SentenceAppendix ? scalar(@Mp3WrapFiles)-1: scalar(@Mp3WrapFiles)) ."|".
|
||||
$Mp3WrapFile;
|
||||
}
|
||||
}
|
||||
|
||||
$filename = md5_hex($hash->{helper}{Text2Speech}[0]) . ".mp3";
|
||||
if(-e $TTS_CacheFileDir."/".$hash->{helper}{Text2Speech}[0]) {
|
||||
# falls eine bestimmte mp3-Datei gespielt werden soll
|
||||
$filename = $hash->{helper}{Text2Speech}[0];
|
||||
} else {
|
||||
$filename = md5_hex($hash->{helper}{Text2Speech}[0]) . ".mp3";
|
||||
}
|
||||
$file = $TTS_CacheFileDir."/".$filename;
|
||||
|
||||
Log3 $hash->{NAME}, 4, "Text2Speech: Bearbeite jetzt den Text: ". $hash->{helper}{Text2Speech}[0];
|
||||
|
||||
if(! -e $file) { # Datei existiert noch nicht im Cache
|
||||
my $fh;
|
||||
|
||||
Log3 $hash->{NAME}, 4, "Text2Speech: Hole URL: ". "http://" . $ttsHost . $ttsPath . uri_escape($hash->{helper}{Text2Speech}[0]);
|
||||
$HttpResponse = GetHttpFile($ttsHost, $ttsPath . uri_escape($hash->{helper}{Text2Speech}[0]));
|
||||
|
||||
$fh = new IO::File ">$file";
|
||||
if(!defined($fh)) {
|
||||
Log3 $hash->{NAME}, 2, "Text2Speech: mp3 Datei <$file> konnte nicht angelegt werden.";
|
||||
return undef;
|
||||
}
|
||||
|
||||
$fh->print($HttpResponse);
|
||||
Log3 $hash->{NAME}, 4, "Text2Speech: Schreibe mp3 in die Datei $file mit ".length($HttpResponse)." Bytes";
|
||||
close($fh);
|
||||
} else {
|
||||
Log3 $hash->{NAME}, 4, "Text2Speech: Datei <$file> bereits vorhanden, erneuter Download nicht notwendig";
|
||||
Text2Speech_Download($hash, $file, $hash->{helper}{Text2Speech}[0]);
|
||||
}
|
||||
|
||||
if(-e $file) { # Datei existiert jetzt
|
||||
@ -530,19 +595,26 @@ sub Text2Speech_DoIt($) {
|
||||
system($cmd);
|
||||
}
|
||||
|
||||
return $hash->{NAME}. "|".
|
||||
"1" ."|".
|
||||
$file;
|
||||
|
||||
} elsif ($TTS_Ressource eq "ESpeak") {
|
||||
$cmd = "sudo espeak -vde+f3 -k5 -s150 \"" . $hash->{helper}{Text2Speech}[0] . "\"";
|
||||
Log3 $hash, 4, "Text2Speech:" .$cmd;
|
||||
system($cmd);
|
||||
}
|
||||
|
||||
return $hash->{NAME}. "|". "1";
|
||||
return $hash->{NAME}. "|".
|
||||
"1" ."|".
|
||||
"";
|
||||
}
|
||||
|
||||
####################################################
|
||||
# Rückgabe der Blockingfunktion
|
||||
# param1: HashName
|
||||
# param2: Anzahl der abgearbeiteten Textbausteine
|
||||
# param3: Dateiname der abgespielt wurde
|
||||
####################################################
|
||||
sub Text2Speech_Done($) {
|
||||
my ($string) = @_;
|
||||
@ -551,8 +623,16 @@ sub Text2Speech_Done($) {
|
||||
my @a = split("\\|",$string);
|
||||
my $hash = $defs{shift(@a)};
|
||||
my $tts_done = shift(@a);
|
||||
#Log 1, "SleepDone: " . $string;
|
||||
my $filename = shift(@a);
|
||||
|
||||
if($filename) {
|
||||
my @text;
|
||||
for(my $i=0; $i<$tts_done; $i++) {
|
||||
push(@text, $hash->{helper}{Text2Speech}[$i]);
|
||||
}
|
||||
Text2Speech_WriteStats($hash, 1, $filename, join(" ", @text));
|
||||
}
|
||||
|
||||
delete($hash->{helper}{RUNNING_PID});
|
||||
splice(@{$hash->{helper}{Text2Speech}}, 0, $tts_done);
|
||||
|
||||
@ -570,6 +650,39 @@ sub Text2Speech_AbortFn($) {
|
||||
Log3 $hash->{NAME}, 2, "Text2Speech: BlockingCall for ".$hash->{NAME}." was aborted";
|
||||
}
|
||||
|
||||
#####################################
|
||||
# Hiermit werden Statistken per DbLogModul gesammelt
|
||||
# Wichitg zur Entscheidung welche Dateien aus dem Cache lange
|
||||
# nicht benutzt und somit gelöscht werden koennen.
|
||||
#
|
||||
# param1: hash
|
||||
# param2: int: 0=indirekt (über mp3wrap); 1=direkt abgespielt
|
||||
# param3: string: Datei
|
||||
# param4: string: Text der als mp3 abgespielt wird
|
||||
#####################################
|
||||
sub Text2Speech_WriteStats($$$$){
|
||||
my($hash, $typ, $file, $text) = @_;
|
||||
my $DbLogDev;
|
||||
|
||||
#suche ein DbLogDevice
|
||||
return undef unless($modules{"DbLog"} && $modules{"DbLog"}{"LOADED"});
|
||||
foreach my $key (keys(%defs)) {
|
||||
if($defs{$key}{TYPE} eq "DbLog") {
|
||||
$DbLogDev = $key;
|
||||
last;
|
||||
}
|
||||
}
|
||||
return undef if($defs{$DbLogDev}{STATE} ne "active"); # muss active sein!
|
||||
|
||||
# den letzten Value von "Usage" ermitteln um dann die Staistik um 1 zu erhoehen.
|
||||
my @LastValue = DbLog_Get($defs{$DbLogDev}, "", "current", "array", "-", "-", $hash->{NAME} ."|". $file.":Usage");
|
||||
my $NewValue = 1;
|
||||
$NewValue = $LastValue[0]{value} + 1 if($LastValue[0]);
|
||||
|
||||
# DbLogHash, DbLogTable, TIMESTAMP, DEVICE, TYPE, EVENT, READING, VALUE, UNIT
|
||||
DbLog_Push($defs{$DbLogDev}, "Current", TimeNow(), $hash->{NAME} ."|". $file, $hash->{TYPE}, $text, "Usage", $NewValue, "");
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
=pod
|
||||
@ -700,6 +813,20 @@ sub Text2Speech_AbortFn($) {
|
||||
Example: <code>silence.mp3</code>
|
||||
</li>
|
||||
|
||||
<li>TTS_FileMapping<br>
|
||||
Definition of mp3files with a custom templatedefinition. Separated by space.
|
||||
All templatedefinitions can used in audiobricks by i>tts</i>.
|
||||
The definition must begin and end with e colon.
|
||||
The mp3files must saved in the given directory by <i>TTS_FIleTemplateDir</i>.<br>
|
||||
<code>attr myTTS TTS_FileMapping ring:ringtone.mp3 beep:MyBeep.mp3</code><br>
|
||||
<code>set MyTTS tts Attention: This is my ringtone :ring: Its loud?</code>
|
||||
</li>
|
||||
|
||||
<li>TTS_FileTemplateDir<br>
|
||||
Directory to save all mp3-files are defined in <i>TTS_FileMapping</i> und <i>TTS_SentenceAppendix</i><br>
|
||||
Optional, Default: <code>cache/templates</code>
|
||||
</li>
|
||||
|
||||
<li><a href="#readingFnAttributes">readingFnAttributes</a></li><br>
|
||||
|
||||
<li><a href="#disable">disable</a><br>
|
||||
@ -847,6 +974,21 @@ sub Text2Speech_AbortFn($) {
|
||||
Beispiel: <code>silence.mp3</code>
|
||||
</li>
|
||||
|
||||
<li>TTS_FileMapping<br>
|
||||
Angabe von möglichen MP3-Dateien mit deren Templatedefinition. Getrennt duch Leerzeichen.
|
||||
Die Templatedefinitionen können in den per <i>tts</i> übergebenen Sprachbausteinen verwendet werden
|
||||
und müssen mit einem beginnenden und endenden Doppelpunkt angegeben werden.
|
||||
Die Dateien müssen im Verzeichnis <i>TTS_FIleTemplateDir</i> gespeichert sein.<br>
|
||||
<code>attr myTTS TTS_FileMapping ring:ringtone.mp3 beep:MyBeep.mp3</code><br>
|
||||
<code>set MyTTS tts Achtung: hier kommt mein Klingelton :ring: War der laut?</code>
|
||||
</li>
|
||||
|
||||
<li>TTS_FileTemplateDir<br>
|
||||
Verzeichnis, in dem die per <i>TTS_FileMapping</i> und <i>TTS_SentenceAppendix</i> definierten
|
||||
MP3-Dateien gespeichert sind.<br>
|
||||
Optional, Default: <code>cache/templates</code>
|
||||
</li>
|
||||
|
||||
<li><a href="#readingFnAttributes">readingFnAttributes</a></li><br>
|
||||
|
||||
<li><a href="#disable">disable</a><br>
|
||||
|
@ -542,4 +542,6 @@
|
||||
|
||||
- Fri Jan 16 2014 (andreas-fey)
|
||||
- Added new module "pilight"
|
||||
|
||||
|
||||
- Sat Jan 18 2014 (tobiasfaust)
|
||||
- Added new Module "Text2Speech"
|
||||
|
Loading…
x
Reference in New Issue
Block a user