2
0
mirror of https://github.com/fhem/fhem-mirror.git synced 2025-04-20 13:26:02 +00:00

Unit.pm: improved template and language support; added scope support

git-svn-id: https://svn.fhem.de/fhem/trunk@12570 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
jpawlowski 2016-11-14 03:38:14 +00:00
parent 5e3a7d1d91
commit 6f16177fd6

View File

@ -5,11 +5,13 @@ use warnings;
use Scalar::Util qw(looks_like_number); use Scalar::Util qw(looks_like_number);
use FHEM::UConv; use FHEM::UConv;
use Data::Dumper; use Data::Dumper;
use Clone qw(clone);
sub Unit_Initialize() { sub Unit_Initialize() {
} }
my $autoscale_m = { my $scales_m = {
autoscale => {
'0' => { format => '%i', scale => 1000, }, '0' => { format => '%i', scale => 1000, },
'0.001' => { format => '%i', scale => 1000, }, '0.001' => { format => '%i', scale => 1000, },
'0.1' => { format => '%.1f', scale => 1, }, '0.1' => { format => '%.1f', scale => 1, },
@ -18,9 +20,8 @@ my $autoscale_m = {
'2.0e3' => { format => '%i', scale => 0.001, }, '2.0e3' => { format => '%i', scale => 0.001, },
'1.0e6' => { format => '%.1f', scale => 0.001, }, '1.0e6' => { format => '%.1f', scale => 0.001, },
'2.0e6' => { format => '%i', scale => 0.001, }, '2.0e6' => { format => '%i', scale => 0.001, },
}; },
my $scales_m = {
'1.0e-12' => { '1.0e-12' => {
'scale_txt_m' => 'p', 'scale_txt_m' => 'p',
'scale_txt_long_m' => { 'scale_txt_long_m' => {
@ -159,6 +160,16 @@ my $scales_cu = {
}, },
}; };
my $scales_t = {
'1' => {},
'60' => {},
'3600' => {},
'86400' => {},
'604800' => {},
'2592000' => {},
'31536000' => {},
};
my $rtype_base = { my $rtype_base = {
# based on https://de.wikipedia.org/wiki/Liste_physikalischer_Gr%C3%B6%C3%9Fen # based on https://de.wikipedia.org/wiki/Liste_physikalischer_Gr%C3%B6%C3%9Fen
@ -524,7 +535,13 @@ my $rtype_base = {
}, },
900 => { 900 => {
txt_base => 'FHEM Readings Type', txt_base => 'FHEM Builtin Readings Type',
tmpl => '%value%',
tmpl_long => '%value%',
},
999 => {
txt_base => 'FHEM User Defined Readings Type',
tmpl => '%value%', tmpl => '%value%',
tmpl_long => '%value%', tmpl_long => '%value%',
}, },
@ -542,7 +559,7 @@ my $rtypes = {
nl => [ 'error', 'on' ], nl => [ 'error', 'on' ],
pl => [ 'error', 'on' ], pl => [ 'error', 'on' ],
}, },
scope => [ 'nok', 'ok' ], scope => [ 'nok|error|0/nok', 'ok|1/ok' ],
}, },
onoff => { onoff => {
@ -554,19 +571,19 @@ my $rtypes = {
nl => [ 'off', 'on' ], nl => [ 'off', 'on' ],
pl => [ 'off', 'on' ], pl => [ 'off', 'on' ],
}, },
scope => [ 'off', 'on' ], scope => [ 'off|0', 'on|1' ],
}, },
bool => { bool => {
ref_base => 900, ref_base => 900,
txt => { txt => {
de => 'wahr/falsch', de => [ 'falsch', 'wahr' ],
en => 'true/false', en => [ 'false', 'true' ],
fr => 'true/false', fr => [ 'false', 'true' ],
nl => 'true/false', nl => [ 'false', 'true' ],
pl => 'true/false', pl => [ 'false', 'true' ],
}, },
scope => [ 'false', 'true' ], scope => [ '0|false', '1|true' ],
}, },
epoch => { epoch => {
@ -590,14 +607,14 @@ my $rtypes = {
nl => 'time hh:mm', nl => 'time hh:mm',
pl => 'time hh:mm', pl => 'time hh:mm',
}, },
scope => '^([0-1]?[0-9]|[0-2]?[0-3]):([0-5]?[0-9])$', scope => '(([0-1]?[0-9]|[0-2]?[0-3]):([0-5]?[0-9]))',
}, },
datetime => { datetime => {
ref_base => 900, ref_base => 900,
txt => 'YYYY-mm-dd hh:mm', txt => 'YYYY-mm-dd hh:mm',
scope => scope =>
'^([1-2][0-9]{3})-(0?[1-9]|1[0-2])-(0?[1-9]|[1-2][0-9]|30|31) (0?[1-9]|1[0-9]|2[0-3]):(0?[1-9]|[1-5][0-9])$', '(([1-2][0-9]{3})-(0?[1-9]|1[0-2])-(0?[1-9]|[1-2][0-9]|30|31) (0?[1-9]|1[0-9]|2[0-3]):(0?[1-9]|[1-5][0-9]))',
}, },
timesec => { timesec => {
@ -609,14 +626,14 @@ my $rtypes = {
nl => 'time hh:mm:ss', nl => 'time hh:mm:ss',
pl => 'time hh:mm:ss', pl => 'time hh:mm:ss',
}, },
scope => '^([0-1]?[0-9]|[0-2]?[0-3]):([0-5]?[0-9]):([0-5]?[0-9])$', scope => '(([0-1]?[0-9]|[0-2]?[0-3]):([0-5]?[0-9]):([0-5]?[0-9]))',
}, },
datetimesec => { datetimesec => {
ref_base => 900, ref_base => 900,
txt => 'YYYY-mm-dd hh:mm:ss', txt => 'YYYY-mm-dd hh:mm:ss',
scope => scope =>
'^([1-2][0-9]{3})-(0?[1-9]|1[0-2])-(0?[1-9]|[1-2][0-9]|30|31) (0?[1-9]|1[0-9]|2[0-3]):(0?[1-9]|[1-5][0-9]):(0?[1-9]|[1-5][0-9])$', '(([1-2][0-9]{3})-(0?[1-9]|1[0-2])-(0?[1-9]|[1-2][0-9]|30|31) (0?[1-9]|1[0-9]|2[0-3]):(0?[1-9]|[1-5][0-9]):(0?[1-9]|[1-5][0-9]))',
}, },
direction => { direction => {
@ -676,8 +693,9 @@ my $rtypes = {
], ],
}, },
scope => [ scope => [
'N', 'NNE', 'NE', 'ENE', 'E', 'ESE', 'SE', 'SSE', 'N|0', 'NNE|1', 'NE|2', 'ENE|3', 'E|4', 'ESE|5',
'S', 'SSW', 'SW', 'WSW', 'W', 'WNW', 'NW', 'NNW' 'SE|6', 'SSE|7', 'S|8', 'SSW|9', 'SW|10', 'WSW|11',
'W|12', 'WNW|13', 'NW|14', 'NNW|15'
], ],
}, },
@ -690,7 +708,7 @@ my $rtypes = {
nl => 'open/closed/tilted', nl => 'open/closed/tilted',
pl => 'open/closed/tilted', pl => 'open/closed/tilted',
}, },
scope => [ 'closed', 'open', 'tilted' ], scope => [ 'closed|0', 'open|1', 'tilted|2' ],
}, },
condition_hum => { condition_hum => {
@ -702,7 +720,7 @@ my $rtypes = {
nl => 'humidity condition', nl => 'humidity condition',
pl => 'humidity condition', pl => 'humidity condition',
}, },
scope => [ 'dry', 'low', 'optimal', 'high', 'wet' ], scope => [ 'dry|0', 'low|1', 'optimal|2', 'high|3', 'wet|4' ],
}, },
condition_uvi => { condition_uvi => {
@ -714,7 +732,7 @@ my $rtypes = {
nl => 'UV condition', nl => 'UV condition',
pl => 'UV condition', pl => 'UV condition',
}, },
scope => [ 'low', 'moderate', 'high', 'veryhigh', 'extreme' ], scope => [ 'low|0', 'moderate|1', 'high|2', 'veryhigh|3', 'extreme|4' ],
}, },
pct => { pct => {
@ -1657,6 +1675,7 @@ my $rtypes = {
scale_m => '1.0e-6', scale_m => '1.0e-6',
ref_sq => 'm', ref_sq => 'm',
scale_sq => '1.0e-2', scale_sq => '1.0e-2',
format => '%.0f',
tmpl => '%value% %suffix%/%suffix_sq%', tmpl => '%value% %suffix%/%suffix_sq%',
tmpl_long => { tmpl_long => {
de => '%value% %txt% pro %txt_sq%', de => '%value% %txt% pro %txt_sq%',
@ -1679,6 +1698,7 @@ my $rtypes = {
scale_m => '1.0e-6', scale_m => '1.0e-6',
ref_sq => 'm', ref_sq => 'm',
scale_sq => '1.0e0', scale_sq => '1.0e0',
format => '%.0f',
tmpl => '%value% %suffix%/%suffix_sq%', tmpl => '%value% %suffix%/%suffix_sq%',
tmpl_long => { tmpl_long => {
de => '%value% %txt% pro %txt_sq%', de => '%value% %txt% pro %txt_sq%',
@ -1701,6 +1721,7 @@ my $rtypes = {
scale_m => '1.0e-3', scale_m => '1.0e-3',
ref_sq => 'm', ref_sq => 'm',
scale_sq => '1.0e-2', scale_sq => '1.0e-2',
format => '%.0f',
tmpl => '%value% %suffix%/%suffix_sq%', tmpl => '%value% %suffix%/%suffix_sq%',
tmpl_long => { tmpl_long => {
de => '%value% %txt% pro %txt_sq%', de => '%value% %txt% pro %txt_sq%',
@ -1723,6 +1744,7 @@ my $rtypes = {
scale_m => '1.0e-3', scale_m => '1.0e-3',
ref_sq => 'm', ref_sq => 'm',
scale_sq => '1.0e0', scale_sq => '1.0e0',
format => '%.0f',
tmpl => '%value% %suffix%/%suffix_sq%', tmpl => '%value% %suffix%/%suffix_sq%',
tmpl_long => { tmpl_long => {
de => '%value% %txt% pro %txt_sq%', de => '%value% %txt% pro %txt_sq%',
@ -1745,6 +1767,7 @@ my $rtypes = {
scale_m => '1.0e0', scale_m => '1.0e0',
ref_sq => 'm', ref_sq => 'm',
scale_sq => '1.0e-2', scale_sq => '1.0e-2',
format => '%.0f',
tmpl => '%value% %suffix%/%suffix_sq%', tmpl => '%value% %suffix%/%suffix_sq%',
tmpl_long => { tmpl_long => {
de => '%value% %txt% pro %txt_sq%', de => '%value% %txt% pro %txt_sq%',
@ -1767,6 +1790,7 @@ my $rtypes = {
scale_m => '1.0e0', scale_m => '1.0e0',
ref_sq => 'm', ref_sq => 'm',
scale_sq => '1.0e0', scale_sq => '1.0e0',
format => '%.0f',
tmpl => '%value% %suffix%/%suffix_sq%', tmpl => '%value% %suffix%/%suffix_sq%',
tmpl_long => { tmpl_long => {
de => '%value% %txt% pro %txt_sq%', de => '%value% %txt% pro %txt_sq%',
@ -1824,6 +1848,7 @@ my $rtypes = {
}; };
my $readingsDB = { my $readingsDB = {
global => {
airpress => { airpress => {
aliasname => 'pressure_hpa', # alias only aliasname => 'pressure_hpa', # alias only
}, },
@ -2205,6 +2230,7 @@ my $readingsDB = {
wind_speed_mps => { wind_speed_mps => {
rtype => 'mps', rtype => 'mps',
}, },
}
}; };
# Find rtype through reading name # Find rtype through reading name
@ -2226,7 +2252,7 @@ sub rname2rtype ($$@) {
$r =~ s/.*[-_](temp)$/$1/i; $r =~ s/.*[-_](temp)$/$1/i;
# rename capital letter containing readings # rename capital letter containing readings
if ( !$readingsDB->{ lc($r) } ) { if ( !$readingsDB->{global}{ lc($r) } ) {
$r =~ s/^([A-Z])(.*)/\l$1$2/; $r =~ s/^([A-Z])(.*)/\l$1$2/;
$r =~ s/([A-Z][a-z0-9]+)[\/\|\-_]?/_$1/g; $r =~ s/([A-Z][a-z0-9]+)[\/\|\-_]?/_$1/g;
} }
@ -2234,31 +2260,31 @@ sub rname2rtype ($$@) {
$r = lc($r); $r = lc($r);
# known aliasname reading names # known aliasname reading names
if ( $readingsDB->{$r}{aliasname} ) { if ( $readingsDB->{global}{$r}{aliasname} ) {
my $dr = $readingsDB->{$r}{aliasname}; my $dr = $readingsDB->{global}{$r}{aliasname};
$return{aliasname} = $dr; $return{aliasname} = $dr;
$return{shortname} = $readingsDB->{$dr}{shortname}; $return{shortname} = $readingsDB->{global}{$dr}{shortname};
$rt = ( $rt = (
$readingsDB->{$dr}{rtype} $readingsDB->{global}{$dr}{rtype}
? $readingsDB->{$dr}{rtype} ? $readingsDB->{global}{$dr}{rtype}
: "-" : "-"
); );
} }
# known standard reading names # known standard reading names
elsif ( $readingsDB->{$r}{shortname} ) { elsif ( $readingsDB->{global}{$r}{shortname} ) {
$return{aliasname} = $reading; $return{aliasname} = $reading;
$return{shortname} = $readingsDB->{$r}{shortname}; $return{shortname} = $readingsDB->{global}{$r}{shortname};
$rt = ( $rt = (
$readingsDB->{$r}{rtype} $readingsDB->{global}{$r}{rtype}
? $readingsDB->{$r}{rtype} ? $readingsDB->{global}{$r}{rtype}
: "-" : "-"
); );
} }
# just guessing the rtype from reading name format # just guessing the rtype from reading name format
elsif ( $r =~ /^.*_([A-Za-z]+)$/i ) { elsif ( $r =~ /^.*_([A-Za-z0-9]+)$/i ) {
$guess = 1; $return{guess} = 1;
$rt = $1; $rt = $1;
} }
@ -2271,10 +2297,12 @@ sub rname2rtype ($$@) {
package main; package main;
# Get value + rtype combined string # Get value + rtype combined string
sub replaceTemplate ($$$;$) { sub replaceTemplate ($$$$;$) {
my ( $device, $reading, $desc, $value ) = @_; my ( $device, $reading, $odesc, $lang, $value ) = @_;
my $l = ( $lang ? lc($lang) : "en" );
my $txt; my $txt;
my $txt_long; my $txt_long;
my $desc = clone($odesc);
my $r = $defs{$device}{READINGS} if ($device); my $r = $defs{$device}{READINGS} if ($device);
return return
@ -2284,9 +2312,87 @@ sub replaceTemplate ($$$;$) {
if ( !defined($value) && defined( $desc->{value} ) ); if ( !defined($value) && defined( $desc->{value} ) );
return $value return $value
if ( !defined($value) if ( !defined($value) || $value eq "" );
|| $value eq ""
|| ( !$desc->{suffix} && !$desc->{symbol} ) ); ##########
# language support
#
# keep only defined language if set
foreach ( keys %{$desc} ) {
if ( defined( $desc->{$_} )
&& ref( $desc->{$_} ) eq "HASH"
&& defined( $desc->{$_}{$l} ) )
{
my $v;
$v = $desc->{$_}{$l};
delete $desc->{$_};
$desc->{$_} = $v if ( defined($v) );
}
}
# add metric name to suffix
$desc->{suffix} = $desc->{scale_txt_m} . $desc->{suffix}
if ( $desc->{suffix}
&& $desc->{scale_txt_m} );
$desc->{txt} = $desc->{scale_txt_long_m} . lc( $desc->{txt} )
if ( $desc->{txt}
&& $desc->{scale_txt_long_m} );
# add square information to suffix and txt
# if no separate suffix_sq and txt_sq was found
$desc->{suffix} = $desc->{suffix} . $desc->{scale_txt_sq}
if (!$desc->{suffix_sq}
&& $desc->{scale_txt_sq} );
$desc->{txt} = $desc->{scale_txt_long_sq} . lc( $desc->{txt} )
if (!$desc->{txt_sq}
&& $desc->{scale_txt_long_sq} );
# add cubic information to suffix and txt
# if no separate suffix_cu and txt_cu was found
$desc->{suffix} = $desc->{suffix} . $desc->{scale_txt_cu}
if (!$desc->{suffix_cu}
&& $desc->{scale_txt_cu} );
$desc->{txt} = $desc->{scale_txt_long_cu} . lc( $desc->{txt} )
if (!$desc->{txt_cu}
&& $desc->{scale_txt_long_cu} );
# add metric name to suffix_sq
$desc->{suffix_sq} = $desc->{scale_txt_m_sq} . $desc->{suffix_sq}
if ( $desc->{suffix_sq}
&& $desc->{scale_txt_m_sq}
&& $desc->{suffix_sq} !~ /$desc->{scale_txt_m_sq}/ );
$desc->{txt_sq} = $desc->{scale_txt_long_m_sq} . lc( $desc->{txt_sq} )
if ( $desc->{txt_sq}
&& $desc->{scale_txt_long_m_sq} );
# # add square information to suffix_sq
$desc->{suffix_sq} = $desc->{suffix_sq} . $desc->{scale_txt_sq}
if ( $desc->{suffix_sq}
&& $desc->{scale_txt_sq} );
$desc->{txt_sq} = $desc->{scale_txt_long_sq} . lc( $desc->{txt_sq} )
if ( $desc->{txt_sq}
&& $desc->{scale_txt_long_sq} );
# add metric name to suffix_cu
$desc->{suffix_cu} = $desc->{scale_txt_m_cu} . $desc->{suffix_cu}
if ( $desc->{suffix_cu}
&& $desc->{scale_txt_m_cu} );
$desc->{txt_cu} = $desc->{scale_txt_long_m_cu} . lc( $desc->{txt_cu} )
if ( $desc->{txt_cu}
&& $desc->{scale_txt_long_m_cu} );
# add cubic information to suffix_cu
$desc->{suffix_cu} = $desc->{suffix_cu} . $desc->{scale_txt_cu}
if ( $desc->{suffix_cu}
&& $desc->{scale_txt_cu} );
$desc->{txt_cu} = $desc->{scale_txt_long_cu} . lc( $desc->{txt_cu} )
if ( $desc->{txt_cu}
&& $desc->{scale_txt_long_cu} );
##########
# template support
#
# shortname # shortname
$txt = '%value% %suffix%'; $txt = '%value% %suffix%';
@ -2334,8 +2440,9 @@ sub replaceTemplate ($$$;$) {
} }
# format a number according to desc and optional format. # format a number according to desc and optional format.
sub formatValue($$$;$$$) { sub formatValue($$$;$$$$) {
my ( $device, $reading, $value, $desc, $format, $lang ) = @_; my ( $device, $reading, $value, $desc, $format, $scope, $lang ) = @_;
$lang = "en" if ( !$lang );
return $value if ( !defined($value) || ref($value) ); return $value if ( !defined($value) || ref($value) );
@ -2347,11 +2454,80 @@ sub formatValue($$$;$$$) {
$value *= $desc->{factor} if ( $desc && $desc->{factor} ); $value *= $desc->{factor} if ( $desc && $desc->{factor} );
$format = $desc->{format} if ( !$format && $desc ); $format = $desc->{format} if ( !$format && $desc );
$format = $autoscale_m if ( !$format );
if ( ref($format) eq 'CODE' ) { # $format = $scales_m->{autoscale} if ( !$format );
$scope = $desc->{scope} if ( !$scope && $desc );
# scope
#
if ( ref($scope) eq 'CODE' && &$scope ) {
$value = $scope->($value);
}
elsif ( ref($scope) eq 'HASH' && looks_like_number($value) ) {
if ( $scope->{min} && $value < $scope->{min} ) {
$value = $scope->{min};
}
elsif ( $scope->{lt} && $value < $scope->{lt} ) {
$value = $scope->{lt};
}
elsif ( $scope->{max} && $value > $scope->{min} ) {
$value = $scope->{max};
}
elsif ( $scope->{gt} && $value > $scope->{gt} ) {
$value = $scope->{gt};
}
elsif ( $scope->{ge} && $value >= $scope->{ge} ) {
$value = $scope->{ge};
}
elsif ( $scope->{le} && $value <= $scope->{le} ) {
$value = $scope->{le};
}
}
elsif ( ref($scope) eq 'ARRAY' ) {
if ( looks_like_number($value)
&& defined( $scope->[$value] )
&& $value =~ /$scope->[$value]/gmi )
{
if ( defined( $desc->{txt}{$lang}[$value] ) ) {
$value = $desc->{txt}{$lang}[$value];
}
else {
$value = $1 if ($1);
$value = $scope->[$value] if ( !$1 );
}
}
else {
foreach ($scope) {
if ( $value =~ /$_/gmi ) {
$value = $1 if ($1);
$value = ${ $scope->{$_} } if ( !$1 );
if ( defined( $desc->{txt}{$lang}[$_] ) ) {
$value = $desc->{txt}{$lang}[$_];
}
elsif ( defined( $desc->{txt}{$lang}[$value] ) ) {
$value = $desc->{txt}{$lang}[$value];
}
last;
}
}
}
}
elsif ( defined($scope) && $scope ne "" && $value =~ /^$scope$/i ) {
$value = $scope->{$1} if ( defined($1) );
}
# format
#
if ( ref($format) eq 'CODE' && &$format ) {
$value = $format->($value); $value = $format->($value);
} }
elsif ( ref($format) eq 'HASH' && looks_like_number($value) ) { elsif ( ref($format) eq 'HASH' && looks_like_number($value) ) {
my $v = abs($value); my $v = abs($value);
foreach my $l ( sort { $b <=> $a } keys( %{$format} ) ) { foreach my $l ( sort { $b <=> $a } keys( %{$format} ) ) {
@ -2362,45 +2538,31 @@ sub formatValue($$$;$$$) {
$value *= $scale if ($scale); $value *= $scale if ($scale);
$value = sprintf( $format->{$l}{format}, $value ) $value = sprintf( $format->{$l}{format}, $value )
if ( $format->{$l}{format} ); if ( $format->{$l}{format} );
# if ($scale) {
# if ( my $scale = $scales->{$scale} ) {
# $suffix .= $scale;
# }
# }
last; last;
} }
} }
} }
elsif ( ref($format) eq 'ARRAY' ) { elsif ( ref($format) eq 'ARRAY' ) {
} }
elsif ($format) {
elsif ( $format && looks_like_number($value) ) {
my $scale = $desc->{scale}; my $scale = $desc->{scale};
$value *= $scale if ($scale); $value *= $scale if ($scale);
$value = sprintf( $format, $value );
# $value = sprintf( $format, $value );
# if ($scale) {
# if ( my $scale = $scales->{$scale} ) {
# $suffix .= $scale;
# }
# }
} }
$desc->{value} = $value; $desc->{value}{$lang} = $value;
my ( $txt, $txt_long ) = replaceTemplate( $device, $reading, $desc, $lang );
my ( $txt, $txt_long ) = replaceTemplate( $device, $reading, $desc );
return ( $txt, $txt_long ) if (wantarray); return ( $txt, $txt_long ) if (wantarray);
return $txt; return $txt;
} }
# find desc and optional format for device:reading # find desc and optional format for device:reading
sub readingsDesc($;$$) { sub readingsDesc($;$) {
my ( $device, $reading, $lang ) = @_; my ( $device, $reading ) = @_;
my $l = ( $lang ? lc($lang) : "en" );
my $desc = getCombinedKeyValAttr( $device, "readingsDesc", $reading ); my $desc = getCombinedKeyValAttr( $device, "readingsDesc", $reading );
my $rtype; my $rtype;
@ -2466,7 +2628,7 @@ sub readingsDesc($;$$) {
} }
} }
if ( defined( $desc->{ref_base} ) ) { $desc->{ref_base} = 999 if ( !defined( $desc->{ref_base} ) );
my $ref = $desc->{ref_base}; my $ref = $desc->{ref_base};
foreach my $k ( keys %{ $rtype_base->{$ref} } ) { foreach my $k ( keys %{ $rtype_base->{$ref} } ) {
$desc->{$k} = $rtype_base->{$ref}{$k} $desc->{$k} = $rtype_base->{$ref}{$k}
@ -2474,115 +2636,19 @@ sub readingsDesc($;$$) {
} }
} }
# keep only defined language if set
foreach ( keys %{$desc} ) {
if ( $desc->{$_}
&& ref( $desc->{$_} ) eq "HASH" )
{
my $v;
$v = $desc->{$_}{$l}
if ( $desc->{$_}{$l} );
delete $desc->{$_};
$desc->{$_} = $v if ($v);
}
}
# add metric name to suffix
$desc->{suffix} = $desc->{scale_txt_m} . $desc->{suffix}
if ( $desc->{suffix}
&& $desc->{scale_txt_m}
&& $desc->{suffix} !~ /^$desc->{scale_txt_m}/ );
$desc->{txt} = $desc->{scale_txt_long_m} . lc( $desc->{txt} )
if ( $desc->{txt}
&& $desc->{scale_txt_long_m}
&& $desc->{txt} !~ /^$desc->{scale_txt_long_m}/ );
# add square information to suffix and txt
# if no separate suffix_sq and txt_sq was found
$desc->{suffix} = $desc->{suffix} . $desc->{scale_txt_sq}
if (!$desc->{suffix_sq}
&& $desc->{scale_txt_sq}
&& $desc->{suffix} !~ /$desc->{scale_txt_sq}/ );
$desc->{txt} = $desc->{scale_txt_long_sq} . lc( $desc->{txt} )
if (!$desc->{txt_sq}
&& $desc->{scale_txt_long_sq}
&& $desc->{suffix} !~ /$desc->{scale_txt_long_sq}/ );
# add cubic information to suffix and txt
# if no separate suffix_cu and txt_cu was found
$desc->{suffix} = $desc->{suffix} . $desc->{scale_txt_cu}
if (!$desc->{suffix_cu}
&& $desc->{scale_txt_cu}
&& $desc->{suffix} !~ /$desc->{scale_txt_cu}/ );
$desc->{txt} = $desc->{scale_txt_long_cu} . lc( $desc->{txt} )
if (!$desc->{txt_cu}
&& $desc->{scale_txt_long_cu}
&& $desc->{txt} !~ /$desc->{scale_txt_long_cu}/ );
# add metric name to suffix_sq
$desc->{suffix_sq} = $desc->{scale_txt_m_sq} . $desc->{suffix_sq}
if ( $desc->{suffix_sq}
&& $desc->{scale_txt_m_sq}
&& $desc->{suffix_sq} !~ /$desc->{scale_txt_m_sq}/ );
$desc->{txt_sq} = $desc->{scale_txt_long_m_sq} . lc( $desc->{txt_sq} )
if ( $desc->{txt_sq}
&& $desc->{scale_txt_long_m_sq}
&& $desc->{txt_sq} !~ /$desc->{scale_txt_long_m_sq}/ );
# # add square information to suffix_sq
$desc->{suffix_sq} = $desc->{suffix_sq} . $desc->{scale_txt_sq}
if ( $desc->{suffix_sq}
&& $desc->{scale_txt_sq}
&& $desc->{suffix_sq} !~ /$desc->{scale_txt_sq}/ );
$desc->{txt_sq} = $desc->{scale_txt_long_sq} . lc( $desc->{txt_sq} )
if ( $desc->{txt_sq}
&& $desc->{scale_txt_long_sq}
&& $desc->{txt_sq} !~ /$desc->{scale_txt_long_sq}/ );
# add metric name to suffix_cu
$desc->{suffix_cu} = $desc->{scale_txt_m_cu} . $desc->{suffix_cu}
if ( $desc->{suffix_cu}
&& $desc->{scale_txt_m_cu}
&& $desc->{suffix_cu} !~ /$desc->{scale_txt_m_cu}/ );
$desc->{txt_cu} = $desc->{scale_txt_long_m_cu} . lc( $desc->{txt_cu} )
if ( $desc->{txt_cu}
&& $desc->{scale_txt_long_m_cu}
&& $desc->{txt_cu} !~ /$desc->{scale_txt_long_m_cu}/ );
# add cubic information to suffix_cu
$desc->{suffix_cu} = $desc->{suffix_cu} . $desc->{scale_txt_cu}
if ( $desc->{suffix_cu}
&& $desc->{scale_txt_cu}
&& $desc->{suffix_cu} !~ /$desc->{scale_txt_cu}/ );
$desc->{txt_cu} = $desc->{scale_txt_long_cu} . lc( $desc->{txt_cu} )
if ( $desc->{txt_cu}
&& $desc->{scale_txt_long_cu}
&& $desc->{txt_cu} !~ /$desc->{scale_txt_long_cu}/ );
}
######################
my $fformat = getCombinedKeyValAttr( $device, "readingsFormat" );
my $format;
$format = $fformat->{$reading}
if ( $reading && defined( $fformat->{$reading} ) );
$format = $format->{$reading} if ( ref($format) eq 'HASH' );
return ( $desc, $format ) if (wantarray);
return $desc; return $desc;
} }
#format device:reading with optional default value and optional desc and optional format #format device:reading with optional default value and optional desc and optional format
sub formatReading($$;$$$$) { sub formatReading($$;$$$$$) {
my ( $device, $reading, $default, $desc, $format, $lang ) = @_; my ( $device, $reading, $default, $desc, $format, $scope, $lang ) = @_;
$desc = readingsDesc( $device, $reading, $lang ) if ( !$desc && $format );
( $desc, $format ) = readingsDesc( $device, $reading, $lang )
if ( !$desc && !$format );
$desc = readingsDesc( $device, $reading ) if ( !$desc );
my $value = ReadingsVal( $device, $reading, undef ); my $value = ReadingsVal( $device, $reading, undef );
$value = $default if ( !defined($value) ); $value = $default if ( !defined($value) );
return formatValue( $device, $reading, $value, $desc, $format, $lang );
return formatValue( $device, $reading, $value, $desc, $format, $scope,
$lang );
} }
# return unit symbol for device:reading # return unit symbol for device:reading
@ -2905,6 +2971,7 @@ sub CommandSetReadingDesc($@) {
if ( $a->[0] eq "?" || $a->[1] eq "?" || !%{$h} ); if ( $a->[0] eq "?" || $a->[1] eq "?" || !%{$h} );
my @rets; my @rets;
my $last;
foreach my $name ( devspec2array( $a->[0], $cl ) ) { foreach my $name ( devspec2array( $a->[0], $cl ) ) {
if ( !defined( $defs{$name} ) ) { if ( !defined( $defs{$name} ) ) {
push @rets, "Please define $name first"; push @rets, "Please define $name first";
@ -2919,6 +2986,7 @@ sub CommandSetReadingDesc($@) {
my $ret = my $ret =
setKeyValAttr( $name, $attribute, $a->[1], $_, $h->{$_} ); setKeyValAttr( $name, $attribute, $a->[1], $_, $h->{$_} );
push @rets, $ret if ($ret); push @rets, $ret if ($ret);
$last = 1 if ( $h->{$_} eq "?" || $h->{$_} eq "" );
} }
next; next;
} }
@ -2934,8 +3002,11 @@ sub CommandSetReadingDesc($@) {
my $ret = my $ret =
setKeyValAttr( $name, $attribute, $reading, $_, $h->{$_} ); setKeyValAttr( $name, $attribute, $reading, $_, $h->{$_} );
push @rets, $ret if ($ret); push @rets, $ret if ($ret);
$last = 1 if ( $h->{$_} eq "?" || $h->{$_} eq "" );
} }
} }
last if ($last);
} }
return join( "\n", @rets ); return join( "\n", @rets );
} }