mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-03-10 09:16:53 +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.
|
# 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.
|
# Do not insert empty lines here, update check depends on it.
|
||||||
- SVN
|
- SVN
|
||||||
|
- feature: DbLog: jokers "%" in device/reading definition are now possible
|
||||||
- feature: SYSMON: new CPU Statistics and Plots
|
- feature: SYSMON: new CPU Statistics and Plots
|
||||||
- feature: changed 10_OWServer.pm and 11_OWDevice.pm to use
|
- feature: changed 10_OWServer.pm and 11_OWDevice.pm to use
|
||||||
NOTIFYDEV (justme1968)
|
NOTIFYDEV (justme1968)
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
# written by Dr. Boris Neubert 2007-12-30
|
# written by Dr. Boris Neubert 2007-12-30
|
||||||
# e-mail: omega at online dot de
|
# 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
|
# e-mail: tobias dot faust at online dot de
|
||||||
#
|
#
|
||||||
##############################################
|
##############################################
|
||||||
@ -17,11 +17,8 @@ use warnings;
|
|||||||
use DBI;
|
use DBI;
|
||||||
use Data::Dumper;
|
use Data::Dumper;
|
||||||
|
|
||||||
sub DbLog($$$);
|
|
||||||
|
|
||||||
################################################################
|
################################################################
|
||||||
sub
|
sub DbLog_Initialize($)
|
||||||
DbLog_Initialize($)
|
|
||||||
{
|
{
|
||||||
my ($hash) = @_;
|
my ($hash) = @_;
|
||||||
|
|
||||||
@ -36,8 +33,7 @@ DbLog_Initialize($)
|
|||||||
}
|
}
|
||||||
|
|
||||||
###############################################################
|
###############################################################
|
||||||
sub
|
sub DbLog_Define($@)
|
||||||
DbLog_Define($@)
|
|
||||||
{
|
{
|
||||||
my ($hash, $def) = @_;
|
my ($hash, $def) = @_;
|
||||||
my @a = split("[ \t][ \t]*", $def);
|
my @a = split("[ \t][ \t]*", $def);
|
||||||
@ -64,8 +60,7 @@ DbLog_Define($@)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#####################################
|
#####################################
|
||||||
sub
|
sub DbLog_Undef($$)
|
||||||
DbLog_Undef($$)
|
|
||||||
{
|
{
|
||||||
my ($hash, $name) = @_;
|
my ($hash, $name) = @_;
|
||||||
my $dbh= $hash->{DBH};
|
my $dbh= $hash->{DBH};
|
||||||
@ -79,8 +74,7 @@ DbLog_Undef($$)
|
|||||||
# DbLog-Instanz aufgerufen
|
# DbLog-Instanz aufgerufen
|
||||||
#
|
#
|
||||||
################################################################
|
################################################################
|
||||||
sub
|
sub DbLog_Attr(@)
|
||||||
DbLog_Attr(@)
|
|
||||||
{
|
{
|
||||||
my @a = @_;
|
my @a = @_;
|
||||||
my $do = 0;
|
my $do = 0;
|
||||||
@ -101,8 +95,7 @@ DbLog_Attr(@)
|
|||||||
# Parsefunktion, abhaengig vom Devicetyp
|
# Parsefunktion, abhaengig vom Devicetyp
|
||||||
#
|
#
|
||||||
################################################################
|
################################################################
|
||||||
sub
|
sub DbLog_ParseEvent($$$)
|
||||||
DbLog_ParseEvent($$$)
|
|
||||||
{
|
{
|
||||||
my ($device, $type, $event)= @_;
|
my ($device, $type, $event)= @_;
|
||||||
my @result;
|
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
|
# MAX
|
||||||
elsif(($type eq "MAX")) {
|
elsif(($type eq "MAX")) {
|
||||||
$unit= "°C" if(lc($reading) =~ m/temp/);
|
$unit= "°C" if(lc($reading) =~ m/temp/);
|
||||||
@ -339,6 +340,60 @@ DbLog_ParseEvent($$$)
|
|||||||
return @result;
|
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
|
# aufgerufen
|
||||||
#
|
#
|
||||||
################################################################
|
################################################################
|
||||||
sub
|
sub DbLog_Log($$) {
|
||||||
DbLog_Log($$)
|
|
||||||
{
|
|
||||||
# Log is my entry, Dev is the entry of the changed device
|
# 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
|
# name and type required for parsing
|
||||||
my $n= $dev->{NAME};
|
my $n= $dev->{NAME};
|
||||||
@ -362,25 +415,15 @@ DbLog_Log($$)
|
|||||||
#my ($sec,$min,$hr,$day,$mon,$yr,$wday,$yday,$isdst)= localtime(time);
|
#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 $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 $max = int(@{$dev->{CHANGED}});
|
||||||
my $ts_0 = TimeNow();
|
my $ts_0 = TimeNow();
|
||||||
my $now = gettimeofday(); # get timestamp in seconds since epoch
|
my $now = gettimeofday(); # get timestamp in seconds since epoch
|
||||||
my $DbLogExclude = AttrVal($dev->{NAME}, "DbLogExclude", undef);
|
my $DbLogExclude = AttrVal($dev->{NAME}, "DbLogExclude", undef);
|
||||||
|
my $DbLogType = AttrVal($hash->{NAME}, "DbLogType", "Current/History");
|
||||||
my $dbh= $log->{DBH};
|
|
||||||
$dbh->{RaiseError} = 1;
|
|
||||||
|
|
||||||
my $DbLogType = AttrVal($log->{NAME}, "DbLogType", "Current/History");
|
|
||||||
|
|
||||||
#one Transaction
|
#one Transaction
|
||||||
eval {
|
#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) );
|
|
||||||
|
|
||||||
for (my $i = 0; $i < $max; $i++) {
|
for (my $i = 0; $i < $max; $i++) {
|
||||||
my $s = $dev->{CHANGED}[$i];
|
my $s = $dev->{CHANGED}[$i];
|
||||||
$s = "" if(!defined($s));
|
$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
|
$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+)$/)) {
|
if(($v2[1] && $reading =~ m/^$v2[0]$/) && ($v2[1] =~ m/^(\d+)$/)) {
|
||||||
#Regexp matcht und MinIntervall ist angegeben
|
#Regexp matcht und MinIntervall ist angegeben
|
||||||
my $lt = $defs{$dev->{NAME}}{Helper}{DBLOG}{$reading}{$log->{NAME}}{TIME};
|
my $lt = $defs{$dev->{NAME}}{Helper}{DBLOG}{$reading}{$hash->{NAME}}{TIME};
|
||||||
my $lv = $defs{$dev->{NAME}}{Helper}{DBLOG}{$reading}{$log->{NAME}}{VALUE};
|
my $lv = $defs{$dev->{NAME}}{Helper}{DBLOG}{$reading}{$hash->{NAME}}{VALUE};
|
||||||
$lt = 0 if(!$lt);
|
$lt = 0 if(!$lt);
|
||||||
$lv = "" if(!$lv);
|
$lv = "" if(!$lv);
|
||||||
|
|
||||||
@ -423,39 +466,14 @@ DbLog_Log($$)
|
|||||||
}
|
}
|
||||||
next if($DoIt == 0);
|
next if($DoIt == 0);
|
||||||
|
|
||||||
$defs{$dev->{NAME}}{Helper}{DBLOG}{$reading}{$log->{NAME}}{TIME} = $now;
|
$defs{$dev->{NAME}}{Helper}{DBLOG}{$reading}{$hash->{NAME}}{TIME} = $now;
|
||||||
$defs{$dev->{NAME}}{Helper}{DBLOG}{$reading}{$log->{NAME}}{VALUE} = $value;
|
$defs{$dev->{NAME}}{Helper}{DBLOG}{$reading}{$hash->{NAME}}{VALUE} = $value;
|
||||||
|
|
||||||
my @is= ($ts, $n, $t, $s, $reading, $value, $unit);
|
DbLog_Push($hash, $DbLogType, $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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$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 "";
|
return "";
|
||||||
}
|
}
|
||||||
@ -467,8 +485,7 @@ DbLog_Log($$)
|
|||||||
# uebergebenes SQL-Format: YYYY-MM-DD HH24:MI:SS
|
# uebergebenes SQL-Format: YYYY-MM-DD HH24:MI:SS
|
||||||
#
|
#
|
||||||
################################################################
|
################################################################
|
||||||
sub
|
sub DbLog_explode_datetime($%) {
|
||||||
DbLog_explode_datetime($%) {
|
|
||||||
my ($t, %def) = @_;
|
my ($t, %def) = @_;
|
||||||
my %retv;
|
my %retv;
|
||||||
|
|
||||||
@ -489,20 +506,19 @@ DbLog_explode_datetime($%) {
|
|||||||
return %retv
|
return %retv
|
||||||
}
|
}
|
||||||
|
|
||||||
sub
|
sub DbLog_implode_datetime($$$$$$) {
|
||||||
DbLog_implode_datetime($$$$$$) {
|
|
||||||
my ($year, $month, $day, $hour, $minute, $second) = @_;
|
my ($year, $month, $day, $hour, $minute, $second) = @_;
|
||||||
my $retv = $year."-".$month."-".$day." ".$hour.":".$minute.":".$second;
|
my $retv = $year."-".$month."-".$day." ".$hour.":".$minute.":".$second;
|
||||||
|
|
||||||
return $retv;
|
return $retv;
|
||||||
}
|
}
|
||||||
|
|
||||||
################################################################
|
################################################################
|
||||||
#
|
#
|
||||||
# Verbindung zur DB aufbauen
|
# Verbindung zur DB aufbauen
|
||||||
#
|
#
|
||||||
################################################################
|
################################################################
|
||||||
sub
|
sub DbLog_Connect($)
|
||||||
DbLog_Connect($)
|
|
||||||
{
|
{
|
||||||
my ($hash)= @_;
|
my ($hash)= @_;
|
||||||
|
|
||||||
@ -575,6 +591,9 @@ DbLog_Connect($)
|
|||||||
#
|
#
|
||||||
# Prozeduren zum Ausfuehren des SQLs
|
# Prozeduren zum Ausfuehren des SQLs
|
||||||
#
|
#
|
||||||
|
# param1: hash
|
||||||
|
# param2: pointer : DBFilehandle
|
||||||
|
# param3: string : SQL
|
||||||
################################################################
|
################################################################
|
||||||
sub
|
sub
|
||||||
DbLog_ExecSQL1($$$)
|
DbLog_ExecSQL1($$$)
|
||||||
@ -618,6 +637,8 @@ DbLog_ExecSQL($$)
|
|||||||
#
|
#
|
||||||
# GET Funktion
|
# GET Funktion
|
||||||
# wird zb. zur Generierung der Plots implizit aufgerufen
|
# wird zb. zur Generierung der Plots implizit aufgerufen
|
||||||
|
# infile : [-|current|history]
|
||||||
|
# outfile: [-|ALL|INT|WEBCHART]
|
||||||
#
|
#
|
||||||
################################################################
|
################################################################
|
||||||
sub
|
sub
|
||||||
@ -632,16 +653,22 @@ DbLog_Get($@)
|
|||||||
" <out> is a prefix, - means stdout\n"
|
" <out> is a prefix, - means stdout\n"
|
||||||
if(int(@a) < 5);
|
if(int(@a) < 5);
|
||||||
shift @a;
|
shift @a;
|
||||||
my $inf = shift @a;
|
my $inf = lc(shift @a);
|
||||||
my $outf = shift @a;
|
my $outf = lc(shift @a);
|
||||||
my $from = shift @a;
|
my $from = shift @a;
|
||||||
my $to = shift @a; # Now @a contains the list of column_specs
|
my $to = shift @a; # Now @a contains the list of column_specs
|
||||||
my ($internal, @fld);
|
my ($internal, @fld);
|
||||||
|
|
||||||
if($outf eq "INT") {
|
if($inf eq "-") {
|
||||||
|
$inf = "history";
|
||||||
|
}
|
||||||
|
|
||||||
|
if($outf eq "int") {
|
||||||
$outf = "-";
|
$outf = "-";
|
||||||
$internal = 1;
|
$internal = 1;
|
||||||
} elsif (uc($outf) eq "WEBCHART") {
|
} elsif($outf eq "array"){
|
||||||
|
|
||||||
|
} elsif(uc($outf) eq "webchart") {
|
||||||
# redirect the get request to the chartQuery function
|
# redirect the get request to the chartQuery function
|
||||||
return chartQuery($hash, @_);
|
return chartQuery($hash, @_);
|
||||||
}
|
}
|
||||||
@ -659,7 +686,8 @@ DbLog_Get($@)
|
|||||||
$to = $to_datetime{datetime};
|
$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 $writeout = 0;
|
||||||
my (@min, @max, @sum, @cnt, @lastv, @lastd);
|
my (@min, @max, @sum, @cnt, @lastv, @lastd);
|
||||||
my (%tstamp, %lasttstamp, $out_tstamp, $out_value, $minval, $maxval); #fuer delta-h/d Berechnung
|
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][2] = $fld[2]; # Default
|
||||||
$readings[$i][3] = $fld[3]; # function
|
$readings[$i][3] = $fld[3]; # function
|
||||||
$readings[$i][4] = $fld[4]; # regexp
|
$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
|
#create new connection for plotfork
|
||||||
@ -687,7 +717,7 @@ DbLog_Get($@)
|
|||||||
$sqlspec{get_timestamp} = "TO_CHAR(TIMESTAMP, 'YYYY-MM-DD HH24:MI:SS')";
|
$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{from_timestamp} = "TO_TIMESTAMP('$from', 'YYYY-MM-DD HH24:MI:SS')";
|
||||||
$sqlspec{to_timestamp} = "TO_TIMESTAMP('$to', '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") {
|
} elsif ($hash->{DBMODEL} eq "ORACLE") {
|
||||||
$sqlspec{get_timestamp} = "TO_CHAR(TIMESTAMP, 'YYYY-MM-DD HH24:MI:SS')";
|
$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{from_timestamp} = "TO_TIMESTAMP('$from', 'YYYY-MM-DD HH24:MI:SS')";
|
||||||
@ -706,7 +736,7 @@ DbLog_Get($@)
|
|||||||
$sqlspec{to_timestamp} = "'$to'";
|
$sqlspec{to_timestamp} = "'$to'";
|
||||||
}
|
}
|
||||||
|
|
||||||
if(uc($outf) eq "ALL") {
|
if($outf =~ m/(all|array)/) {
|
||||||
$sqlspec{all} = ",TYPE,EVENT,UNIT";
|
$sqlspec{all} = ",TYPE,EVENT,UNIT";
|
||||||
} else {
|
} else {
|
||||||
$sqlspec{all} = "";
|
$sqlspec{all} = "";
|
||||||
@ -724,33 +754,46 @@ DbLog_Get($@)
|
|||||||
$minval = 999999;
|
$minval = 999999;
|
||||||
$maxval = -999999;
|
$maxval = -999999;
|
||||||
|
|
||||||
my $stm= "SELECT
|
my $stm;
|
||||||
$sqlspec{get_timestamp},
|
$stm = "SELECT
|
||||||
VALUE
|
$sqlspec{get_timestamp},
|
||||||
$sqlspec{all}
|
DEVICE,
|
||||||
FROM history
|
READING,
|
||||||
WHERE
|
VALUE
|
||||||
DEVICE = '".$readings[$i]->[0]."'
|
$sqlspec{all} ";
|
||||||
AND READING = '".$readings[$i]->[1]."'
|
|
||||||
AND TIMESTAMP > $sqlspec{from_timestamp}
|
|
||||||
AND TIMESTAMP < $sqlspec{to_timestamp}
|
|
||||||
ORDER BY TIMESTAMP";
|
|
||||||
|
|
||||||
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) ||
|
my $sth= $dbh->prepare($stm) ||
|
||||||
return "Cannot prepare statement $stm: $DBI::errstr";
|
return "Cannot prepare statement $stm: $DBI::errstr";
|
||||||
my $rc= $sth->execute() ||
|
my $rc= $sth->execute() ||
|
||||||
return "Cannot execute statement $stm: $DBI::errstr";
|
return "Cannot execute statement $stm: $DBI::errstr";
|
||||||
|
|
||||||
if(uc($outf) eq "ALL") {
|
if($outf =~ m/(all|array)/) {
|
||||||
$sth->bind_columns(undef, \$sql_timestamp, \$sql_value, \$type, \$event, \$unit);
|
$sth->bind_columns(undef, \$sql_timestamp, \$sql_device, \$sql_reading, \$sql_value, \$type, \$event, \$unit);
|
||||||
|
|
||||||
$retval .= "Timestamp: Device, Type, Event, Reading, Value, Unit\n";
|
|
||||||
$retval .= "=====================================================\n";
|
|
||||||
}
|
}
|
||||||
else {
|
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()) {
|
while($sth->fetch()) {
|
||||||
@ -840,8 +883,13 @@ DbLog_Get($@)
|
|||||||
|
|
||||||
###################### Ausgabe ###########################
|
###################### Ausgabe ###########################
|
||||||
if($writeout) {
|
if($writeout) {
|
||||||
if(uc($outf) eq "ALL") {
|
if ($outf =~ m/(all)/) {
|
||||||
$retval .= sprintf("%s: %s, %s, %s, %s, %s, %s\n", $out_tstamp, $readings[$i]->[0], $type, $event, $readings[$i]->[1], $out_value, $unit);
|
# 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 {
|
} else {
|
||||||
$out_tstamp =~ s/\ /_/g; #needed by generating plots
|
$out_tstamp =~ s/\ /_/g; #needed by generating plots
|
||||||
$retval .= "$out_tstamp $out_value\n";
|
$retval .= "$out_tstamp $out_value\n";
|
||||||
@ -873,12 +921,17 @@ DbLog_Get($@)
|
|||||||
$out_value = sprintf("%g", $maxval - $minval);
|
$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}, $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");
|
$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);
|
if($outf =~ m/(all)/) {
|
||||||
} else {
|
$retval .= sprintf("%s: %s %s %s %s %s %s\n", $out_tstamp, $sql_device, $type, $event, $sql_reading, $out_value, $unit);
|
||||||
$out_tstamp =~ s/\ /_/g; #needed by generating plots
|
|
||||||
$retval .= "$out_tstamp $out_value\n";
|
} 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
|
# DatenTrenner setzen
|
||||||
$retval .= "#$readings[$i]->[0]";
|
$retval .= "#$readings[$i]->[0]";
|
||||||
@ -911,8 +964,13 @@ DbLog_Get($@)
|
|||||||
if($internal) {
|
if($internal) {
|
||||||
$internal_data = \$retval;
|
$internal_data = \$retval;
|
||||||
return undef;
|
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.
|
contains the last event for any given reading and device.
|
||||||
The columns have the following meaning:
|
The columns have the following meaning:
|
||||||
<ol>
|
<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>VALUE: actual reading extracted from event,
|
||||||
<li>DEVICE: device name, e.g. <code>Wetterstation</code></li>
|
e.g. <code>71</code></li>
|
||||||
<li>TYPE: device type, e.g. <code>KS300</code></li>
|
<li>UNIT: unit extracted from event, e.g. <code>%</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>
|
|
||||||
</ol>
|
</ol>
|
||||||
The content of VALUE is optimized for automated post-processing, e.g.
|
The content of VALUE is optimized for automated post-processing, e.g.
|
||||||
<code>yes</code> is translated to <code>1</code>
|
<code>yes</code> is translated to <code>1</code>
|
||||||
@ -1284,11 +1341,25 @@ sub chartQuery($@) {
|
|||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<li><in><br>
|
<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>
|
<li><out><br>
|
||||||
A dummy parameter for FileLog compatibility. Set it to <code>-</code>
|
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
|
to check the output for plot-computing.<br>
|
||||||
<code>all</code> to get all columns from Database.</li>
|
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>
|
<li><from> / <to><br>
|
||||||
Used to select the data. Please use the following timeformat or
|
Used to select the data. Please use the following timeformat or
|
||||||
an initial substring of it:<br>
|
an initial substring of it:<br>
|
||||||
@ -1299,9 +1370,9 @@ sub chartQuery($@) {
|
|||||||
Syntax: <device>:<reading>:<default>:<fn>:<regexp><br>
|
Syntax: <device>:<reading>:<default>:<fn>:<regexp><br>
|
||||||
<ul>
|
<ul>
|
||||||
<li><device><br>
|
<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>
|
<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>
|
||||||
<li><default><br>
|
<li><default><br>
|
||||||
no implemented yet
|
no implemented yet
|
||||||
@ -1344,6 +1415,9 @@ sub chartQuery($@) {
|
|||||||
Examples:
|
Examples:
|
||||||
<ul>
|
<ul>
|
||||||
<li><code>get myDbLog - - 2012-11-10 2012-11-20 KS300:temperature</code></li>
|
<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>
|
<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>
|
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>
|
<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
|
definiert in <code><configfilename></code>. (Vergleiche
|
||||||
Beipspielkonfigurationsdatei in <code>contrib/dblog/db.conf</code>).<br>
|
Beipspielkonfigurationsdatei in <code>contrib/dblog/db.conf</code>).<br>
|
||||||
Die Konfiguration ist in einer sparaten Datei abgelegt um das Datenbankpasswort
|
Die Konfiguration ist in einer sparaten Datei abgelegt um das Datenbankpasswort
|
||||||
nicht in Klartext in der FHEM-Haupt-Konfigurationsdatei speichern zu müssen.
|
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>
|
Ansonsten wäre es mittels des <a href="../docs/commandref.html#list">list</a>
|
||||||
Befehls einfach auslesbar.
|
Befehls einfach auslesbar.
|
||||||
<br><br>
|
<br><br>
|
||||||
|
|
||||||
Die Perl-Module <code>DBI</code> and <code>DBD::<dbtype></code>
|
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).
|
falls die eigene Distribution diese nicht schon mitbringt).
|
||||||
<br><br>
|
<br><br>
|
||||||
|
|
||||||
@ -1487,28 +1561,28 @@ sub chartQuery($@) {
|
|||||||
Ein Beispielcode zum Erstellen einer MySQL/PostGreSQL Datenbak ist in
|
Ein Beispielcode zum Erstellen einer MySQL/PostGreSQL Datenbak ist in
|
||||||
<code>contrib/dblog/<DBType>_create.sql</code> zu finden.
|
<code>contrib/dblog/<DBType>_create.sql</code> zu finden.
|
||||||
Die Datenbank beinhaltet 2 Tabellen: <code>current</code> und
|
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
|
pro Device und Reading. In der Tabelle <code>history</code> sind alle
|
||||||
Events historisch gespeichert.
|
Events historisch gespeichert.
|
||||||
|
|
||||||
Die Tabellenspalten haben folgende Bedeutung:
|
Die Tabellenspalten haben folgende Bedeutung:
|
||||||
<ol>
|
<ol>
|
||||||
<li>TIMESTAMP: Zeitpunkt des Events, z.B. <code>2007-12-30 21:45:22</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>DEVICE: name des Devices, z.B. <code>Wetterstation</code></li>
|
||||||
<li>TYPE: Type des Devices, z.B. <code>KS300</code></li>
|
<li>TYPE: Type des Devices, z.B. <code>KS300</code></li>
|
||||||
<li>EVENT: das auftretende Event als volle Zeichenkette
|
<li>EVENT: das auftretende Event als volle Zeichenkette
|
||||||
z.B. <code>humidity: 71 (%)</code></li>
|
z.B. <code>humidity: 71 (%)</code></li>
|
||||||
<li>READING: Name des Readings, ermittelt aus dem Event,
|
<li>READING: Name des Readings, ermittelt aus dem Event,
|
||||||
z.B. <code>humidity</code></li>
|
z.B. <code>humidity</code></li>
|
||||||
|
|
||||||
<li>VALUE: aktueller Wert des Readings, ermittelt aus dem Event,
|
<li>VALUE: aktueller Wert des Readings, ermittelt aus dem Event,
|
||||||
z.B. <code>71</code></li>
|
z.B. <code>71</code></li>
|
||||||
<li>UNIT: Einheit, ermittelt aus dem Event, z.B. <code>%</code></li>
|
<li>UNIT: Einheit, ermittelt aus dem Event, z.B. <code>%</code></li>
|
||||||
</ol>
|
</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>
|
z.B. <code>yes</code> ist transformiert nach <code>1</code>
|
||||||
<br><br>
|
<br><br>
|
||||||
Die gespeicherten Werte können mittels GET Funktion angezeigt werden:
|
Die gespeicherten Werte können mittels GET Funktion angezeigt werden:
|
||||||
<ul>
|
<ul>
|
||||||
<code>get myDbLog - - 2012-11-10 2012-11-10 KS300:temperature</code>
|
<code>get myDbLog - - 2012-11-10 2012-11-10 KS300:temperature</code>
|
||||||
</ul>
|
</ul>
|
||||||
@ -1516,7 +1590,6 @@ sub chartQuery($@) {
|
|||||||
<b>Beispiel:</b>
|
<b>Beispiel:</b>
|
||||||
<ul>
|
<ul>
|
||||||
<code>Speichert alles in der Datenbank</code><br>
|
<code>Speichert alles in der Datenbank</code><br>
|
||||||
|
|
||||||
<code>define myDbLog DbLog /etc/fhem/db.conf .*:.*</code>
|
<code>define myDbLog DbLog /etc/fhem/db.conf .*:.*</code>
|
||||||
</ul>
|
</ul>
|
||||||
</ul>
|
</ul>
|
||||||
@ -1531,37 +1604,49 @@ sub chartQuery($@) {
|
|||||||
<code>get <name> <infile> <outfile> <from>
|
<code>get <name> <infile> <outfile> <from>
|
||||||
<to> <column_spec> </code>
|
<to> <column_spec> </code>
|
||||||
<br><br>
|
<br><br>
|
||||||
Ließt Daten aus der Datenbank. Wird durch die Frontends benutzt um Plots
|
Liesst Daten aus der Datenbank. Wird durch die Frontends benutzt um Plots
|
||||||
zu generieren ohne selbst auf die Datenank zugreifen zu müssen.
|
zu generieren ohne selbst auf die Datenank zugreifen zu mössen.
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<li><in><br>
|
<li><in><br>
|
||||||
Ein Dummy Parameter um eine Kompatibilität zum Filelog herzustellen.
|
Ein Parameter um eine Kompatibilität zum Filelog herzustellen.
|
||||||
Dieser Parameter ist immer auf <code>-</code> zu setzen.
|
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>
|
||||||
<li><out><br>
|
<li><out><br>
|
||||||
Ein Dummy Parameter um eine Kompatibilität zum Filelog herzustellen.
|
Ein Parameter um eine Kompatibilität zum Filelog herzustellen.
|
||||||
Dieser Parameter ist immer auf <code>-</code> zu setzen um die
|
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>
|
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
|
Folgende Ausprägungen sind zugelassen:<br>
|
||||||
Spalten der Datenbank ausgegeben.
|
<ul>
|
||||||
</li>
|
<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>
|
<li><from> / <to><br>
|
||||||
Wird benutzt um den Zeitraum der Daten einzugrenzen. Es ist das folgende
|
Wird benutzt um den Zeitraum der Daten einzugrenzen. Es ist das folgende
|
||||||
Zeitformat oder ein Teilstring davon zu benutzen:<br>
|
Zeitformat oder ein Teilstring davon zu benutzen:<br>
|
||||||
<ul><code>YYYY-MM-DD_HH24:MI:SS</code></ul></li>
|
<ul><code>YYYY-MM-DD_HH24:MI:SS</code></ul></li>
|
||||||
<li><column_spec><br>
|
<li><column_spec><br>
|
||||||
Für jede column_spec Gruppe wird ein Datenset zurückgegeben welches
|
För jede column_spec Gruppe wird ein Datenset zuröckgegeben welches
|
||||||
durch einen Kommentar getrennt wird. Dieser Kommentar repräsentiert
|
durch einen Kommentar getrennt wird. Dieser Kommentar repräsentiert
|
||||||
die column_spec.<br>
|
die column_spec.<br>
|
||||||
Syntax: <device>:<reading>:<default>:<fn>:<regexp><br>
|
Syntax: <device>:<reading>:<default>:<fn>:<regexp><br>
|
||||||
<ul>
|
<ul>
|
||||||
<li><device><br>
|
<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>
|
<li><reading><br>
|
||||||
Das REading des angegebenen Devices zur Datenselektion.
|
Das Reading des angegebenen Devices zur Datenselektion.<br>
|
||||||
Achtung: Groß/Kleinschreibung beachten!
|
Es kann ein % als Jokerzeichen angegeben werden.<br>
|
||||||
|
Achtung: Gross/Kleinschreibung beachten!
|
||||||
</li>
|
</li>
|
||||||
<li><default><br>
|
<li><default><br>
|
||||||
Zur Zeit noch nicht implementiert.
|
Zur Zeit noch nicht implementiert.
|
||||||
@ -1571,17 +1656,17 @@ sub chartQuery($@) {
|
|||||||
<ul>
|
<ul>
|
||||||
<li>int<br>
|
<li>int<br>
|
||||||
Ermittelt den Zahlenwert ab dem Anfang der Zeichenkette aus der
|
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>
|
||||||
<li>int<digit><br>
|
<li>int<digit><br>
|
||||||
Ermittelt den Zahlenwert ab dem Anfang der Zeichenkette aus der
|
Ermittelt den Zahlenwert ab dem Anfang der Zeichenkette aus der
|
||||||
Spalte "VALUE", inclusive negativen Vorzeichen und Dezimaltrenner.
|
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>
|
||||||
<li>delta-h / delta-d<br>
|
<li>delta-h / delta-d<br>
|
||||||
Ermittelt die relative Veränderung eines Zahlenwertes pro Stunde
|
Ermittelt die relative Veränderung eines Zahlenwertes pro Stunde
|
||||||
oder pro Tag. Wird benutzt z.B. für Spalten die einen
|
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
|
hochlaufenden Zähler enthalten wie im Falle för ein KS300 Regenzähler
|
||||||
oder dem 1-wire Modul OWCOUNT.
|
oder dem 1-wire Modul OWCOUNT.
|
||||||
</li>
|
</li>
|
||||||
<li>delta-ts<br>
|
<li>delta-ts<br>
|
||||||
@ -1590,19 +1675,19 @@ sub chartQuery($@) {
|
|||||||
</li>
|
</li>
|
||||||
</ul></li>
|
</ul></li>
|
||||||
<li><regexp><br>
|
<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>
|
<br>
|
||||||
Bitte zur Beachtung: Diese Zeichenkette darf keine Leerzeichen
|
Bitte zur Beachtung: Diese Zeichenkette darf keine Leerzeichen
|
||||||
enthalten da diese sonst als <column_spec> Trennung
|
enthalten da diese sonst als <column_spec> Trennung
|
||||||
interpretiert werden und alles nach dem Leerzeichen als neue
|
interpretiert werden und alles nach dem Leerzeichen als neue
|
||||||
<column_spec> gesehen wird.<br>
|
<column_spec> gesehen wird.<br>
|
||||||
<b>Schlüsselwörter</b>
|
<b>Schlösselwörter</b>
|
||||||
<li>$val ist der aktuelle Wert die die Datenbank für ein Device/Reading ausgibt.</li>
|
<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>$ts ist der aktuelle Timestamp des Logeintrages.</li>
|
||||||
<li>Wird als $val das Schlüsselwort "hide" zurückgegeben, so wird dieser Logeintrag nicht
|
<li>Wird als $val das Schlösselwort "hide" zuröckgegeben, so wird dieser Logeintrag nicht
|
||||||
ausgegeben, trotzdem aber für die Zeitraumberechnung verwendet.</li>
|
ausgegeben, trotzdem aber för die Zeitraumberechnung verwendet.</li>
|
||||||
<li>Wird als $val das Schlüsselwort "ignore" zurückgegeben, so wird dieser Logeintrag
|
<li>Wird als $val das Schlösselwort "ignore" zuröckgegeben, so wird dieser Logeintrag
|
||||||
nicht für eine Folgeberechnung verwendet.</li>
|
nicht för eine Folgeberechnung verwendet.</li>
|
||||||
</li>
|
</li>
|
||||||
</ul></li>
|
</ul></li>
|
||||||
</ul>
|
</ul>
|
||||||
@ -1610,39 +1695,42 @@ sub chartQuery($@) {
|
|||||||
<b>Beispiele:</b>
|
<b>Beispiele:</b>
|
||||||
<ul>
|
<ul>
|
||||||
<li><code>get myDbLog - - 2012-11-10 2012-11-20 KS300:temperature</code></li>
|
<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>
|
<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>
|
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 - 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 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>
|
<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>
|
<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>
|
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>
|
<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-
|
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
|
einträgen ermittelt. Die Zeiten werden bei den on-Meldungen nicht ausgegeben welche einer Abschaltzeit
|
||||||
entsprechen würden.</li>
|
entsprechen wörden.</li>
|
||||||
</ul>
|
</ul>
|
||||||
<br><br>
|
<br><br>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<b>Get</b> für die Nutzung von webcharts
|
<b>Get</b> för die Nutzung von webcharts
|
||||||
<ul>
|
<ul>
|
||||||
<code>get <name> <infile> <outfile> <from>
|
<code>get <name> <infile> <outfile> <from>
|
||||||
<to> <device> <querytype> <xaxis> <yaxis> <savename> </code>
|
<to> <device> <querytype> <xaxis> <yaxis> <savename> </code>
|
||||||
<br><br>
|
<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>
|
<br>
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<li><name><br>
|
<li><name><br>
|
||||||
Der Name des definierten DbLogs, so wie er in der fhem.cfg angegeben wurde.</li>
|
Der Name des definierten DbLogs, so wie er in der fhem.cfg angegeben wurde.</li>
|
||||||
<li><in><br>
|
<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>
|
Dieser Parameter ist immer auf <code>-</code> zu setzen.</li>
|
||||||
<li><out><br>
|
<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.
|
Dieser Parameter ist auf <code>webchart</code> zu setzen um die Charting Get Funktion zu nutzen.
|
||||||
</li>
|
</li>
|
||||||
<li><from> / <to><br>
|
<li><from> / <to><br>
|
||||||
@ -1652,32 +1740,32 @@ sub chartQuery($@) {
|
|||||||
<li><device><br>
|
<li><device><br>
|
||||||
Ein String, der das abzufragende Device darstellt.</li>
|
Ein String, der das abzufragende Device darstellt.</li>
|
||||||
<li><querytype><br>
|
<li><querytype><br>
|
||||||
Ein String, der die zu verwendende Abfragemethode darstellt. Zur Zeit unterstützte Werte sind: <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>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>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>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>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>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>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>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>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>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>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>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>yearstats</code> um Statistiken för einen Wert (yaxis) för ein Jahr abzufragen.<br>
|
||||||
</li>
|
</li>
|
||||||
<li><xaxis><br>
|
<li><xaxis><br>
|
||||||
Ein String, der die X-Achse repräsentiert</li>
|
Ein String, der die X-Achse repräsentiert</li>
|
||||||
<li><yaxis><br>
|
<li><yaxis><br>
|
||||||
Ein String, der die Y-Achse repräsentiert</li>
|
Ein String, der die Y-Achse repräsentiert</li>
|
||||||
<li><savename><br>
|
<li><savename><br>
|
||||||
Ein String, unter dem ein Chart in der Datenbank gespeichert werden soll</li>
|
Ein String, unter dem ein Chart in der Datenbank gespeichert werden soll</li>
|
||||||
<li><chartconfig><br>
|
<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>
|
<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>
|
<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>
|
</ul>
|
||||||
<br><br>
|
<br><br>
|
||||||
Beispiele:
|
Beispiele:
|
||||||
@ -1685,16 +1773,16 @@ sub chartQuery($@) {
|
|||||||
<li><code>get logdb - webchart "" "" "" getcharts</code><br>
|
<li><code>get logdb - webchart "" "" "" getcharts</code><br>
|
||||||
Liefert alle gespeicherten Charts aus der Datenbank</li>
|
Liefert alle gespeicherten Charts aus der Datenbank</li>
|
||||||
<li><code>get logdb - webchart "" "" "" getdevices</code><br>
|
<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>
|
<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>
|
<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>
|
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>
|
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>
|
<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>
|
<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>
|
</ul>
|
||||||
<br><br>
|
<br><br>
|
||||||
</ul>
|
</ul>
|
||||||
@ -1709,11 +1797,11 @@ sub chartQuery($@) {
|
|||||||
</ul>
|
</ul>
|
||||||
<br>
|
<br>
|
||||||
Wenn DbLog genutzt wird, wird in alle Devices das Attribut <i>DbLogExclude</i>
|
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
|
damit matchenden Readings von einem Logging aus. Einzelne Regexp werden durch
|
||||||
Kommata getrennt. Ist MinIntervall angegeben, so wird der Logeintrag nur
|
Kommata getrennt. Ist MinIntervall angegeben, so wird der Logeintrag nur
|
||||||
dann nicht geloggt, wenn das Intervall noch nicht erreicht und der Wert des
|
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>
|
<br>
|
||||||
<b>Beispiele</b>
|
<b>Beispiele</b>
|
||||||
<ul>
|
<ul>
|
||||||
|
@ -62,6 +62,8 @@ sub Text2Speech_Initialize($)
|
|||||||
" TTS_UseMP3Wrap:0,1".
|
" TTS_UseMP3Wrap:0,1".
|
||||||
" TTS_MplayerCall".
|
" TTS_MplayerCall".
|
||||||
" TTS_SentenceAppendix".
|
" TTS_SentenceAppendix".
|
||||||
|
" TTS_FileMapping".
|
||||||
|
" TTS_FileTemplateDir".
|
||||||
" ".$readingFnAttributes;
|
" ".$readingFnAttributes;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -145,6 +147,10 @@ sub Text2Speech_Attr(@) {
|
|||||||
my $hash = $defs{$a[1]};
|
my $hash = $defs{$a[1]};
|
||||||
my $value = $a[3];
|
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") {
|
if($a[2] eq "TTS_Delemiter" && $a[0] ne "del") {
|
||||||
return "wrong delemiter syntax: [+-]a[lfn]. \n".
|
return "wrong delemiter syntax: [+-]a[lfn]. \n".
|
||||||
" Example 1: +an~\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 "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));
|
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);
|
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") {
|
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_Ressource = AttrVal($hash->{NAME}, "TTS_Ressource", "Google");
|
||||||
my $TTS_Delemiter = AttrVal($hash->{NAME}, "TTS_Delemiter", undef);
|
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_ForceSplit = 0;
|
||||||
my $TTS_AddDelemiter;
|
my $TTS_AddDelemiter;
|
||||||
@ -351,12 +374,30 @@ sub Text2Speech_PrepareSpeech($$) {
|
|||||||
@text = $hash->{helper}{Text2Speech} if($hash->{helper}{Text2Speech}[0]);
|
@text = $hash->{helper}{Text2Speech} if($hash->{helper}{Text2Speech}[0]);
|
||||||
push(@text, $t);
|
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, $TTS_Delemiter, $TTS_ForceSplit, $TTS_AddDelemiter);
|
||||||
@text = Text2Speech_SplitString(\@text, 100, "(?<=[\\.!?])\\s*", 0, "");
|
@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, ";", 0, "al");
|
@text = Text2Speech_SplitString(\@text, 100, ";", 0, "al");
|
||||||
@text = Text2Speech_SplitString(\@text, 100, "und", 0, "af");
|
@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;
|
@{$hash->{helper}{Text2Speech}} = @text;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
@ -370,7 +411,7 @@ sub Text2Speech_PrepareSpeech($$) {
|
|||||||
# param3: string: Delemiter
|
# param3: string: Delemiter
|
||||||
# param4: int : 1 -> es wird am Delemiter gesplittet
|
# param4: int : 1 -> es wird am Delemiter gesplittet
|
||||||
# 0 -> es wird nur gesplittet, wenn Stringlänge länger als MaxChar
|
# 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
|
# Splittet die Texte aus $hash->{helper}->{Text2Speech} anhand des
|
||||||
# Delemiters, wenn die Stringlänge MaxChars übersteigt.
|
# Delemiters, wenn die Stringlänge MaxChars übersteigt.
|
||||||
@ -395,7 +436,7 @@ sub Text2Speech_SplitString(@$$$$){
|
|||||||
for(my $j=0; $j<(@b); $j++) {
|
for(my $j=0; $j<(@b); $j++) {
|
||||||
$b[$j] = $b[$j] . $Delemiter if($AddDelemiter eq "al"); # Am Satzende wieder hinzufügen.
|
$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.
|
$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]);
|
push(@newText, $b[$j]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -434,6 +475,33 @@ sub Text2Speech_BuildMplayerCmdString($$) {
|
|||||||
return $cmd;
|
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($) {
|
sub Text2Speech_DoIt($) {
|
||||||
my ($hash) = @_;
|
my ($hash) = @_;
|
||||||
@ -445,7 +513,6 @@ sub Text2Speech_DoIt($) {
|
|||||||
|
|
||||||
if($TTS_Ressource eq "Google") {
|
if($TTS_Ressource eq "Google") {
|
||||||
|
|
||||||
my $HttpResponse;
|
|
||||||
my $filename;
|
my $filename;
|
||||||
my $file;
|
my $file;
|
||||||
|
|
||||||
@ -459,30 +526,35 @@ sub Text2Speech_DoIt($) {
|
|||||||
if(AttrVal($hash->{NAME}, "TTS_UseMP3Wrap", 0)) {
|
if(AttrVal($hash->{NAME}, "TTS_UseMP3Wrap", 0)) {
|
||||||
# benutze das Tool MP3Wrap um bereits einzelne vorhandene Sprachdateien
|
# benutze das Tool MP3Wrap um bereits einzelne vorhandene Sprachdateien
|
||||||
# zusammenzuführen. Ziel: sauberer Sprachfluss
|
# zusammenzuführen. Ziel: sauberer Sprachfluss
|
||||||
my @Mp3WrapArray;
|
my @Mp3WrapFiles;
|
||||||
my $Mp3WrapText = "";
|
my @Mp3WrapText;
|
||||||
my $TTS_SentenceAppendix = AttrVal($hash->{NAME}, "TTS_SentenceAppendix", undef); #muss eine mp3-Datei sein, ohne Pfadangabe
|
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}}) {
|
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;
|
$file = $TTS_CacheFileDir."/".$filename;
|
||||||
if(-e $file) {
|
if(-e $file) {
|
||||||
push(@Mp3WrapArray, $file);
|
push(@Mp3WrapFiles, $file);
|
||||||
$Mp3WrapText .= $t;
|
push(@Mp3WrapText, $t);
|
||||||
|
#Text2Speech_WriteStats($hash, 0, $file, $t);
|
||||||
} else {last;}
|
} else {last;}
|
||||||
}
|
}
|
||||||
|
|
||||||
push(@Mp3WrapArray, $TTS_CacheFileDir ."/".$TTS_SentenceAppendix) if($TTS_SentenceAppendix);
|
push(@Mp3WrapFiles, $TTS_SentenceAppendix) if($TTS_SentenceAppendix);
|
||||||
|
|
||||||
if(scalar(@Mp3WrapArray) >= 2) {
|
if(scalar(@Mp3WrapFiles) >= 2) {
|
||||||
Log3 $hash->{NAME}, 4, "Text2Speech: Bearbeite per MP3Wrap jetzt den Text: ". $Mp3WrapText;
|
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";
|
my $Mp3WrapFile = $TTS_CacheFileDir ."/". $Mp3WrapPrefix . "_MP3WRAP.mp3";
|
||||||
|
|
||||||
if(! -e $Mp3WrapFile) {
|
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);;
|
$cmd .= " >/dev/null" if($verbose < 5);;
|
||||||
|
|
||||||
Log3 $hash->{NAME}, 4, "Text2Speech: " .$cmd;
|
Log3 $hash->{NAME}, 4, "Text2Speech: " .$cmd;
|
||||||
@ -492,36 +564,29 @@ sub Text2Speech_DoIt($) {
|
|||||||
$cmd = Text2Speech_BuildMplayerCmdString($hash, $Mp3WrapFile);
|
$cmd = Text2Speech_BuildMplayerCmdString($hash, $Mp3WrapFile);
|
||||||
Log3 $hash->{NAME}, 4, "Text2Speech:" .$cmd;
|
Log3 $hash->{NAME}, 4, "Text2Speech:" .$cmd;
|
||||||
system($cmd);
|
system($cmd);
|
||||||
|
#Text2Speech_WriteStats($hash, 1, $Mp3WrapFile, join(" ", @Mp3WrapText));
|
||||||
} else {
|
} else {
|
||||||
Log3 $hash->{NAME}, 2, "Text2Speech: Mp3Wrap Datei konnte nicht angelegt werden.";
|
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;
|
$file = $TTS_CacheFileDir."/".$filename;
|
||||||
|
|
||||||
Log3 $hash->{NAME}, 4, "Text2Speech: Bearbeite jetzt den Text: ". $hash->{helper}{Text2Speech}[0];
|
Log3 $hash->{NAME}, 4, "Text2Speech: Bearbeite jetzt den Text: ". $hash->{helper}{Text2Speech}[0];
|
||||||
|
|
||||||
if(! -e $file) { # Datei existiert noch nicht im Cache
|
if(! -e $file) { # Datei existiert noch nicht im Cache
|
||||||
my $fh;
|
Text2Speech_Download($hash, $file, $hash->{helper}{Text2Speech}[0]);
|
||||||
|
|
||||||
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";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(-e $file) { # Datei existiert jetzt
|
if(-e $file) { # Datei existiert jetzt
|
||||||
@ -530,19 +595,26 @@ sub Text2Speech_DoIt($) {
|
|||||||
system($cmd);
|
system($cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return $hash->{NAME}. "|".
|
||||||
|
"1" ."|".
|
||||||
|
$file;
|
||||||
|
|
||||||
} elsif ($TTS_Ressource eq "ESpeak") {
|
} elsif ($TTS_Ressource eq "ESpeak") {
|
||||||
$cmd = "sudo espeak -vde+f3 -k5 -s150 \"" . $hash->{helper}{Text2Speech}[0] . "\"";
|
$cmd = "sudo espeak -vde+f3 -k5 -s150 \"" . $hash->{helper}{Text2Speech}[0] . "\"";
|
||||||
Log3 $hash, 4, "Text2Speech:" .$cmd;
|
Log3 $hash, 4, "Text2Speech:" .$cmd;
|
||||||
system($cmd);
|
system($cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $hash->{NAME}. "|". "1";
|
return $hash->{NAME}. "|".
|
||||||
|
"1" ."|".
|
||||||
|
"";
|
||||||
}
|
}
|
||||||
|
|
||||||
####################################################
|
####################################################
|
||||||
# Rückgabe der Blockingfunktion
|
# Rückgabe der Blockingfunktion
|
||||||
# param1: HashName
|
# param1: HashName
|
||||||
# param2: Anzahl der abgearbeiteten Textbausteine
|
# param2: Anzahl der abgearbeiteten Textbausteine
|
||||||
|
# param3: Dateiname der abgespielt wurde
|
||||||
####################################################
|
####################################################
|
||||||
sub Text2Speech_Done($) {
|
sub Text2Speech_Done($) {
|
||||||
my ($string) = @_;
|
my ($string) = @_;
|
||||||
@ -551,8 +623,16 @@ sub Text2Speech_Done($) {
|
|||||||
my @a = split("\\|",$string);
|
my @a = split("\\|",$string);
|
||||||
my $hash = $defs{shift(@a)};
|
my $hash = $defs{shift(@a)};
|
||||||
my $tts_done = 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});
|
delete($hash->{helper}{RUNNING_PID});
|
||||||
splice(@{$hash->{helper}{Text2Speech}}, 0, $tts_done);
|
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";
|
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;
|
1;
|
||||||
|
|
||||||
=pod
|
=pod
|
||||||
@ -700,6 +813,20 @@ sub Text2Speech_AbortFn($) {
|
|||||||
Example: <code>silence.mp3</code>
|
Example: <code>silence.mp3</code>
|
||||||
</li>
|
</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="#readingFnAttributes">readingFnAttributes</a></li><br>
|
||||||
|
|
||||||
<li><a href="#disable">disable</a><br>
|
<li><a href="#disable">disable</a><br>
|
||||||
@ -847,6 +974,21 @@ sub Text2Speech_AbortFn($) {
|
|||||||
Beispiel: <code>silence.mp3</code>
|
Beispiel: <code>silence.mp3</code>
|
||||||
</li>
|
</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="#readingFnAttributes">readingFnAttributes</a></li><br>
|
||||||
|
|
||||||
<li><a href="#disable">disable</a><br>
|
<li><a href="#disable">disable</a><br>
|
||||||
|
@ -542,4 +542,6 @@
|
|||||||
|
|
||||||
- Fri Jan 16 2014 (andreas-fey)
|
- Fri Jan 16 2014 (andreas-fey)
|
||||||
- Added new module "pilight"
|
- Added new module "pilight"
|
||||||
|
|
||||||
|
- Sat Jan 18 2014 (tobiasfaust)
|
||||||
|
- Added new Module "Text2Speech"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user