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

34_SWAP.pm: added flash command for panStamp NRG ota update (by mgehre)

added internals and readings cleanup on ProductCode change (by mgehre)
            added createUnknownReadings attribute
            see also: http://forum.fhem.de/index.php/topic,30589.msg233658.html#msg233658


git-svn-id: https://svn.fhem.de/fhem/trunk@7295 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
justme-1968 2014-12-21 20:25:45 +00:00
parent be7954933e
commit a183a561cb

View File

@ -86,6 +86,7 @@ SWAP_Initialize($)
$hash->{AttrFn} = "SWAP_Attr"; $hash->{AttrFn} = "SWAP_Attr";
$hash->{AttrList} = "IODev". $hash->{AttrList} = "IODev".
" ignore:1,0". " ignore:1,0".
" createUnknownReadings:1,0".
" $readingFnAttributes" . " $readingFnAttributes" .
" ProductCode:".join(",", sort keys %{$products}); " ProductCode:".join(",", sort keys %{$products});
@ -242,7 +243,7 @@ SWAP_Define($$)
my @a = split("[ \t][ \t]*", $def); my @a = split("[ \t][ \t]*", $def);
if(@a != 3 && @a != 4 ) { if(@a != 3 && @a != 4 ) {
my $msg = "wrong syntax: define <name> SWAP <addr>[.<reg>] [<ProductCode>]"; my $msg = "wrong syntax: define <name> SWAP <addr>[.<reg>]";
Log3 undef, 2, $msg; Log3 undef, 2, $msg;
return $msg; return $msg;
} }
@ -299,6 +300,9 @@ SWAP_Define($$)
$hash->{product} = $products->{$productcode} if( defined($productcode) && defined($products->{$productcode} ) ); $hash->{product} = $products->{$productcode} if( defined($productcode) && defined($products->{$productcode} ) );
$hash->{DEF} = $hash->{addr};
$hash->{DEF} .= $hash->{reg} if( $hash->{reg} );
SWAP_Send($hash, $addr, QUERY, "00" ); SWAP_Send($hash, $addr, QUERY, "00" );
return undef; return undef;
@ -624,7 +628,6 @@ SWAP_Set($@)
} }
} }
} elsif( $cmd eq "readDeviceXML" ) { } elsif( $cmd eq "readDeviceXML" ) {
my $productcode = $attr{$name}{ProductCode} if( defined($attr{$name}{ProductCode} ) ); my $productcode = $attr{$name}{ProductCode} if( defined($attr{$name}{ProductCode} ) );
if( defined($products->{$productcode} ) ) { if( defined($products->{$productcode} ) ) {
@ -633,9 +636,34 @@ SWAP_Set($@)
} else { } else {
return "can't read deviceXML for unknown ProductCode"; return "can't read deviceXML for unknown ProductCode";
} }
} elsif( $cmd eq "clearUnconfirmed" ) { } elsif( $cmd eq "clearUnconfirmed" ) {
delete( $hash->{sentList} ); delete( $hash->{sentList} );
delete ($hash->{SWAP_Sent_unconfirmed}); delete ($hash->{SWAP_Sent_unconfirmed});
} elsif( $cmd eq "flash" ) {
my $firmwareFolder = "./FHEM/firmware/";
my $hexfile;
if ($cnt < 2) {
#No argument to flash
return "Device has no product code; you need to specify a firmeware to flash" if( !defined($attr{$name}{ProductCode} ) );
$hexfile = $firmwareFolder . "SWAP_$attr{$name}{ProductCode}.hex";
} else {
if ( substr($arg, 0, 1) eq "/" ) {
#absolute path provided
$hexfile = $arg;
} else {
#Product code provided
$hexfile = $firmwareFolder . "SWAP_$arg.hex";
}
}
open FILE, $hexfile or return "Could not open $hexfile";
Log3 $name, 1, "Flashing $hexfile to $name";
my @a = <FILE>;
@a = map { substr $_, 3, -1 } @a;
$hash->{HEXFILE} = [ @a ];
SWAP_Send($hash, $addr, COMMAND, "03", "05" ); #Set "System State" to "Flash"
} else { } else {
return SetExtensions($hash, $list, $name, @aa); return SetExtensions($hash, $list, $name, @aa);
return "Unknown argument $cmd, choose one of ".$list; return "Unknown argument $cmd, choose one of ".$list;
@ -840,7 +868,7 @@ SWAP_updateReadings($$$)
readingsBulkUpdate($hash, "state", (substr($data,0,6) eq "000000"?"off":$data)) if( defined($attr{$name}{ProductCode}) && $attr{$name}{ProductCode} eq '0000002200000003' && $reg == 0x0B ); readingsBulkUpdate($hash, "state", (substr($data,0,6) eq "000000"?"off":$data)) if( defined($attr{$name}{ProductCode}) && $attr{$name}{ProductCode} eq '0000002200000003' && $reg == 0x0B );
readingsBulkUpdate($hash, "state", $data) if( $hash->{reg} && hex($hash->{reg}) == $reg ); readingsBulkUpdate($hash, "state", $data) if( $hash->{reg} && hex($hash->{reg}) == $reg );
readingsEndUpdate($hash,1); readingsEndUpdate($hash,1);
} else { } elsif( AttrVal($name, "createUnknownReadings",0 ) ) {
readingsBeginUpdate($hash); readingsBeginUpdate($hash);
readingsBulkUpdate($hash, $rid, $data); readingsBulkUpdate($hash, $rid, $data);
readingsBulkUpdate($hash, "state", $data) if( $hash->{reg} && hex($hash->{reg}) == $reg ); readingsBulkUpdate($hash, "state", $data) if( $hash->{reg} && hex($hash->{reg}) == $reg );
@ -924,6 +952,18 @@ SWAP_Parse($$)
Log3 $name, 4, $sname ." -> ". $dname ." ($hop,$secu-$nonce): ". $function_codes{$func} . " ". $rname . " ". $regname . ($data?":":"") . $data; Log3 $name, 4, $sname ." -> ". $dname ." ($hop,$secu-$nonce): ". $function_codes{$func} . " ". $rname . " ". $regname . ($data?":":"") . $data;
if( $raddr eq "01" and $func == QUERY and $rid eq "0B" and length($data) == 4 ) {
#Uploading firmware
my $lineno = hex($data);
Log3 $name, 4, "Serving firmware request of $src for line no. $lineno";
if (exists($shash->{HEXFILE})) {
SWAP_Send($shash, "00", STATUS, "0B", $data.$shash->{HEXFILE}[$lineno] );
} else {
Log3 $name, 1, "SWAP device $src is in flash mode, but no hex file is configured. Use 'set $name flash HEXFILE'";
}
}
return $rname if( $raddr eq "01" ); return $rname if( $raddr eq "01" );
return $rname if( $func == QUERY ); return $rname if( $func == QUERY );
@ -944,10 +984,11 @@ SWAP_Parse($$)
#product code #product code
if( $reg == 0x00 ) { if( $reg == 0x00 ) {
my $first = !defined($rhash->{"SWAP_00-ProductCode"});
my $productcode = $data; my $productcode = $data;
SWAP_Attr( "set", $rname, "ProductCode", $productcode ) if( !defined( $attr{$rname}{ProductCode} ) ); my $first = !defined($rhash->{"SWAP_00-ProductCode"}) || $rhash->{"SWAP_00-ProductCode"} ne $productcode;
SWAP_Attr( "set", $rname, "ProductCode", $productcode ) if( $first );
if( !defined($products->{$productcode}->{registers}) ){ if( !defined($products->{$productcode}->{registers}) ){
SWAP_readDeviceXML( $rhash, $productcode ); SWAP_readDeviceXML( $rhash, $productcode );
@ -1119,6 +1160,26 @@ SWAP_Attr(@)
my $hash = $defs{$name}; my $hash = $defs{$name};
my $productcode = $attrVal; my $productcode = $attrVal;
#Product code changed (due to flash of different firmware or switch of addresses)
if( defined( $attr{$name}{ProductCode} ) && $attr{$name}{ProductCode} ne $productcode) {
my $oldproductcode = "None";
$oldproductcode = $attr{$name}{ProductCode} if( defined( $attr{$name}{ProductCode} ) );
Log3 $name, 3, "Device $name changed product code from $oldproductcode to $productcode";
#Delete all SWAP_HEX-
foreach my $key (keys %{$hash}) {
if ($key =~ "^SWAP_[0-9A-F][0-9A-F]-") {
Log3 $name, 5, "Deleting $key";
delete $hash->{$key};
}
}
#Delete all readings
foreach my $key (keys %{$hash->{READINGS}}) {
Log3 $name, 5, "Deleting reading $key";
delete $hash->{READINGS}{$key};
}
}
if( !defined($products->{$productcode}->{registers}) ){ if( !defined($products->{$productcode}->{registers}) ){
SWAP_readDeviceXML( $hash, $productcode ); SWAP_readDeviceXML( $hash, $productcode );
} }
@ -1230,6 +1291,12 @@ SWAP_Attr(@)
<li>clearUnconfirmed<br> <li>clearUnconfirmed<br>
clears the list of unconfirmed messages. clears the list of unconfirmed messages.
</li><br> </li><br>
<li>flash [&lt;productCode&gt|&lt;firmwareFile&gt;]<br>
will initiate an ota firmware update. only possible for panStamp NRG devices.<br>
no params -> will use the <code>SWAP_&lt;current productCode&gt;.hex</code> file from the FHEM/firmware directory.<br>
&lt;productCode&gt -> will use the <code>SWAP_&lt;productCode&gt;.hex</code> file from the FHEM/firmware directory.<br>
&lt;firmwareFile&gt; -> will use &lt;firmwareFile&gt; as the absolute file name of the hex file.<br>
</li><br>
</ul> </ul>
<a name="SWAP_Get"></a> <a name="SWAP_Get"></a>
@ -1255,6 +1322,9 @@ SWAP_Attr(@)
<a name="SWAP_Attr"></a> <a name="SWAP_Attr"></a>
<b>Attributes</b> <b>Attributes</b>
<ul> <ul>
<li>createUnknownReadings<br>
Create readings for unknown registers, i.e. registers not defined in the device xml file.
</li><br>
<li>ProductCode<br> <li>ProductCode<br>
ProductCode of the device. used to read the register configuration from the device definition file. ProductCode of the device. used to read the register configuration from the device definition file.
hast to be set manualy for devices that are in sleep mode during definition. hast to be set manualy for devices that are in sleep mode during definition.