2
0
mirror of https://github.com/fhem/fhem-mirror.git synced 2025-03-09 20:57:11 +00:00

fhem.pl: add map to json2nameValue (Forum #94629)

git-svn-id: https://svn.fhem.de/fhem/trunk@18003 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
rudolfkoenig 2018-12-19 10:45:16 +00:00
parent 34e744ea76
commit 82f5fa2123
2 changed files with 69 additions and 24 deletions

View File

@ -28,6 +28,7 @@ MQTT2_DEVICE_Initialize($)
disable:0,1
disabledForIntervals
getList:textField-long
jsonMap:textField-long
model
readingList:textField-long
setList:textField-long
@ -112,7 +113,8 @@ MQTT2_DEVICE_Parse($$)
if($code =~ m/^{.*}$/s) {
$code = EvalSpecials($code, ("%TOPIC"=>$topic, "%EVENT"=>$value,
"%DEVICETOPIC"=>$hash->{DEVICETOPIC}, "%NAME"=>$hash->{NAME}));
"%DEVICETOPIC"=>$hash->{DEVICETOPIC}, "%NAME"=>$hash->{NAME},
"%JSONMAP","\$defs{$dev}{JSONMAP}"));
my $ret = AnalyzePerlCommand(undef, $code);
if($ret && ref $ret eq "HASH") {
readingsBeginUpdate($hash);
@ -165,7 +167,7 @@ MQTT2_DEVICE_Parse($$)
if(keys %{$ret}) {
$topic =~ m,.*/([^/]+),;
my $prefix = ($1 && $1 !~m/^0x[0-9a-f]+$/i) ? "${1}_" : ""; # 91394
$add = "{ json2nameValue(\$EVENT, '$prefix') }";
$add = "{ json2nameValue(\$EVENT, '$prefix', \$JSONMAP) }";
}
}
if(!$add) {
@ -345,7 +347,8 @@ MQTT2_DEVICE_Attr($$)
if($par2 =~ m/^{.*}$/) {
my $ret = perlSyntaxCheck($par2,
("%TOPIC"=>1, "%EVENT"=>"0 1 2 3 4 5 6 7 8 9",
"%NAME"=>$dev, "%DEVICETOPIC"=>$hash->{DEVICETOPIC}));
"%NAME"=>$dev, "%DEVICETOPIC"=>$hash->{DEVICETOPIC},
"%JSONMAP"=>""));
return $ret if($ret);
} else {
return "unsupported character in readingname $par2"
@ -385,6 +388,17 @@ MQTT2_DEVICE_Attr($$)
}
}
if($attrName eq "jsonMap") {
if($type eq "set") {
my @ret = split(/[: \r\n]/, $param);
return "jsonMap: Odd number of elements" if(int(@ret) % 2);
my %ret = @ret;
$hash->{JSONMAP} = \%ret;
} else {
delete $hash->{JSONMAP};
}
}
return undef;
}
@ -577,6 +591,21 @@ zigbee2mqtt_devStateIcon255($)
</li><br>
<a name="jsonMap"></a>
<li>jsonMap oldReading1:newReading1 oldReading2:newReading2...<br>
space or newline separated list of oldReading:newReading pairs.<br>
Used in the automatically generated readingList json2nameValue function
to map the generated reading name to a better one. E.g.
<ul><code>
attr m2d jsonMap SENSOR_AM2301_Humidity:Humidity<br>
attr m2d readingList tele/sonoff/SENSOR:.* { json2nameValue($EVENT, 'SENSOR_', $JSONMAP) }
</code></ul>
The special newReading value of 0 will prevent creating a reading for
oldReading.
<br>
</li><br>
<a name="readingList"></a>
<li>readingList &lt;regexp&gt; [readingName|perl-Expression] ...
<br>
@ -596,9 +625,9 @@ zigbee2mqtt_devStateIcon255($)
Notes:
<ul>
<li>in the perl expression the variables $TOPIC, $NAME, $DEVICETOPIC
and $EVENT are available (the letter containing the whole message),
as well as $EVTPART0, $EVTPART1, ... each containing a single word of
the message.</li>
$JSONMAP and $EVENT are available (the letter containing the whole
message), as well as $EVTPART0, $EVTPART1, ... each containing a
single word of the message.</li>
<li>the helper function json2nameValue($EVENT) can be used to parse a
json encoded value. Importing all values from a Sonoff device with a
Tasmota firmware can be done with:

View File

@ -132,7 +132,8 @@ sub getAllGets($;$);
sub getAllSets($;$);
sub getPawList($);
sub getUniqueId();
sub json2nameValue($;$);
sub json2nameValue($;$$);
sub json2reading($$;$$);
sub latin1ToUtf8($);
sub myrename($$$);
sub notifyRegexpChanged($$);
@ -4918,13 +4919,15 @@ toJSON($)
}
#############################
# will return a hash of name:value pairs.
# Note: doesnt know arrays, just objects and simple types
# will return a hash of name:value pairs. in is a json_string, prefix will be
# prepended to each name, map is a hash for mapping the names
sub
json2nameValue($;$)
json2nameValue($;$$)
{
my ($in,$prefix) = @_;
my ($in, $prefix, $map) = @_;
$prefix = "" if(!defined($prefix));
$map = eval $map if($map && !ref($map)); # passing hash through AnalyzeCommand
$map = {} if(!$map);
my %ret;
sub
@ -4974,22 +4977,34 @@ json2nameValue($;$)
return ($t, ""); # error
}
sub eObj($$$$$);
sub
eObj($$$$$)
setVal($$$$$)
{
my ($ret,$name,$val,$in,$prefix) = @_;
my ($ret,$map,$prefix,$name,$val) = @_;
$name = "$prefix$name";
if(defined($map->{$name})) {
return if(!$map->{$name});
$name = $map->{$name};
}
$ret->{$name} = $val;
};
sub eObj($$$$$$);
sub
eObj($$$$$$)
{
my ($ret,$map,$name,$val,$in,$prefix) = @_;
if($val =~ m/^"/) {
($val, $in) = lStr($val);
$val =~ s/\\u([0-9A-F]{4})/chr(hex($1))/gsie; # toJSON reverse
$ret->{"$prefix$name"} = $val;
setVal($ret, $map, $prefix, $name, $val);
} elsif($val =~ m/^{/) { # }
($val, $in) = lObj($val, '{', '}');
my $r2 = json2nameValue($val);
foreach my $k (keys %{$r2}) {
$ret->{"$prefix${name}_$k"} = $r2->{$k};
setVal($ret, $map, $prefix, "${name}_$k", $r2->{$k});
}
} elsif($val =~ m/^\[/) {
@ -4997,21 +5012,22 @@ json2nameValue($;$)
my $idx = 1;
$val =~ s/^\s*//;
while($val) {
$val = eObj($ret, $name."_$idx", $val, $val, $prefix);
$val = eObj($ret, $map, $name."_$idx", $val, $val, $prefix);
$val =~ s/^\s*,\s*//;
$val =~ s/\s*$//;
$idx++;
}
} elsif($val =~ m/^([0-9.-]+)(.*)$/s) {
$ret->{"$prefix$name"} = $1;
setVal($ret, $map, $prefix, $name, $1);
$in = $2;
} elsif($val =~ m/^(true|false)(.*)$/s) {
$ret->{"$prefix$name"} = $1;
setVal($ret, $map, $prefix, $name, $1);
$in = $2;
} elsif($val =~ m/^(null)(.*)$/s) {
$ret->{"$prefix$name"} = undef;
setVal($ret, $map, $prefix, $name, undef);
$in = $2;
} else {
@ -5026,7 +5042,7 @@ json2nameValue($;$)
while($in =~ m/^\s*"([^"]+)"\s*:\s*(.*)$/s) {
my ($name,$val) = ($1,$2);
$name =~ s/[^a-z0-9._\-\/]/_/gsi;
$in = eObj(\%ret, $name, $val, $in, $prefix);
$in = eObj(\%ret, $map, $name, $val, $in, $prefix);
$in =~ s/^\s*,\s*//;
}
return \%ret;
@ -5034,15 +5050,15 @@ json2nameValue($;$)
# generate readings from the json string (parsed by json2reading) for $hash
sub
json2reading($$)
json2reading($$;$$)
{
my ($hash, $json) = @_;
my ($hash, $json, $prefix, $map) = @_;
$hash = $defs{$hash} if(ref($hash) ne "HASH");
return "json2reading: first arg is not a FHEM device"
if(!$hash || ref $hash ne "HASH" || !$hash->{TYPE});
my $ret = json2nameValue($json);
my $ret = json2nameValue($json, $prefix, $map);
if($ret && ref $ret eq "HASH") {
readingsBeginUpdate($hash);
foreach my $k (keys %{$ret}) {