2
0
mirror of https://github.com/fhem/fhem-mirror.git synced 2025-04-22 08:11:44 +00:00

MYSENSORS (_DEVICE): update cref; OTA-related changes, #120942

git-svn-id: https://svn.fhem.de/fhem/trunk@24446 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
Beta-User 2021-05-15 14:04:30 +00:00
parent 0c96571dfd
commit f812e120d4
2 changed files with 150 additions and 131 deletions

View File

@ -40,13 +40,13 @@ use GPUtils qw(:all);
sub main::MYSENSORS_Initialize { goto &Initialize }; sub main::MYSENSORS_Initialize { goto &Initialize };
my %sets = ( my %sets = (
"connect" => [], connect => [qw(noArg)],
"disconnect" => [], disconnect => [qw(noArg)],
"inclusion-mode" => [qw(on off)], 'inclusion-mode' => [qw(on off)],
); );
my %gets = ( my %gets = (
"version" => "" version => ''
); );
my @clients = qw( my @clients = qw(
@ -58,7 +58,7 @@ sub Initialize {
my $hash = shift // return; my $hash = shift // return;
# Provider # Provider
$hash->{Clients} = join (':',@clients); $hash->{Clients} = join q{:}, @clients;
$hash->{ReadyFn} = \&Ready; $hash->{ReadyFn} = \&Ready;
$hash->{ReadFn} = \&Read; $hash->{ReadFn} = \&Read;
@ -73,13 +73,13 @@ sub Initialize {
qw( qw(
autocreate:1 autocreate:1
requestAck:1 requestAck:1
first-sensorid first-sensorid:selectnumbers,1,1,255,0,lin
last-sensorid last-sensorid:selectnumbers,2,1,255,0,lin
stateFormat stateFormat
OTA_firmwareConfig OTA_firmwareConfig
) )
); );
$hash->{AttrList} = $hash->{AttrList} = join(" ", @attrList); $hash->{AttrList} = $hash->{AttrList} = join q{ }, @attrList;
return; return;
} }
@ -103,6 +103,7 @@ BEGIN { GP_Import(
Log3 Log3
FileRead FileRead
IsDisabled IsDisabled
looks_like_number
) )
) )
}; };
@ -417,15 +418,15 @@ sub Set {
.join ',', @{$sets{$_}} : $_} sort keys %sets) .join ',', @{$sets{$_}} : $_} sort keys %sets)
if !defined($sets{$command}); if !defined($sets{$command});
if ($command eq "connect") { if ($command eq 'connect') {
return Start($hash); return Start($hash);
} }
if ($command eq "disconnect") { if ($command eq 'disconnect') {
return Stop($hash); return Stop($hash);
} }
if ($command eq "inclusion-mode") { if ($command eq 'inclusion-mode') {
sendMessage($hash, sendMessage($hash,
radioId => 0, radioId => 0,
childId => 0, childId => 0,
@ -447,7 +448,7 @@ sub Attr {
my $value = shift; my $value = shift;
my $hash = $defs{$name}; my $hash = $defs{$name};
if ($attribute eq "autocreate" && $init_done) { if ($attribute eq 'autocreate' && $init_done) {
my $mode = $command eq "set" ? 1 : 0; my $mode = $command eq "set" ? 1 : 0;
$hash->{'inclusion-mode'} = $mode; $hash->{'inclusion-mode'} = $mode;
return sendMessage($hash, return sendMessage($hash,
@ -459,8 +460,8 @@ sub Attr {
); );
} }
if ($attribute eq "requestAck") { if ($attribute eq 'requestAck') {
if ($command eq "set") { if ($command eq 'set') {
$hash->{ack} = 1; $hash->{ack} = 1;
} else { } else {
$hash->{ack} = 0; $hash->{ack} = 0;
@ -470,12 +471,17 @@ sub Attr {
return; return;
} }
if ($attribute eq "OTA_firmwareConfig") { if ($attribute eq 'OTA_firmwareConfig') {
return; if ($command eq 'set') {
return getFirmwareTypes($hash, 'set', $value);
} else {
delete $hash->{'.fwList'};
return;
}
} }
if ($attribute eq "disable") { if ($attribute eq 'disable') {
return Stop($hash) if $command eq "set" && $value; return Stop($hash) if $command eq 'set' && $value;
InternalTimer(time(), "MYSENSORS::Start", $hash,0); InternalTimer(time, "MYSENSORS::Start", $hash,0);
return; return;
} }
return; return;
@ -485,9 +491,10 @@ sub Start {
my $hash = shift // return; my $hash = shift // return;
my ($dev) = split m{\s+}xms, $hash->{DEF}; my ($dev) = split m{\s+}xms, $hash->{DEF};
$hash->{DeviceName} = $dev; $hash->{DeviceName} = $dev;
if (!AttrVal($hash->{NAME},"stateFormat",0)) { if (!AttrVal($hash->{NAME},'stateFormat',0)) {
CommandAttr(undef, "$hash->{NAME} stateFormat connection") CommandAttr(undef, "$hash->{NAME} stateFormat connection")
} }
getFirmwareTypes($hash, 'start');
return if IsDisabled( $hash->{NAME} ); return if IsDisabled( $hash->{NAME} );
DevIo_CloseDev($hash); DevIo_CloseDev($hash);
return DevIo_OpenDev($hash, 0, "MYSENSORS::Init"); return DevIo_OpenDev($hash, 0, "MYSENSORS::Init");
@ -497,13 +504,13 @@ sub Stop {
my $hash = shift // return; my $hash = shift // return;
DevIo_CloseDev($hash); DevIo_CloseDev($hash);
RemoveInternalTimer($hash); RemoveInternalTimer($hash);
readingsSingleUpdate($hash,"connection","disconnected",1); readingsSingleUpdate($hash,'connection','disconnected',1);
return; return;
} }
sub Ready { sub Ready {
my $hash = shift // return; my $hash = shift // return;
return DevIo_OpenDev($hash, 1, "MYSENSORS::Init") if($hash->{STATE} eq "disconnected"); return DevIo_OpenDev($hash, 1, "MYSENSORS::Init") if($hash->{STATE} eq 'disconnected');
if(defined($hash->{USBDev})) { if(defined($hash->{USBDev})) {
my $po = $hash->{USBDev}; my $po = $hash->{USBDev};
my ( $BlockingFlags, $InBytes, $OutBytes, $ErrorFlags ) = $po->status; my ( $BlockingFlags, $InBytes, $OutBytes, $ErrorFlags ) = $po->status;
@ -515,8 +522,8 @@ sub Ready {
sub Init { sub Init {
my $hash = shift // return; my $hash = shift // return;
my $name = $hash->{NAME}; my $name = $hash->{NAME};
$hash->{'inclusion-mode'} = AttrVal($name,"autocreate",0); $hash->{'inclusion-mode'} = AttrVal($name,'autocreate',0);
$hash->{ack} = AttrVal($name,"requestAck",0); $hash->{ack} = AttrVal($name,'requestAck',0);
$hash->{outstandingAck} = 0; $hash->{outstandingAck} = 0;
if ($hash->{ack}) { if ($hash->{ack}) {
GP_ForallClients($hash,sub { GP_ForallClients($hash,sub {
@ -529,7 +536,7 @@ sub Init {
}; };
}); });
} }
readingsSingleUpdate($hash,"connection","connected",1); readingsSingleUpdate($hash,'connection','connected',1);
return sendMessage($hash, return sendMessage($hash,
radioId => 0, radioId => 0,
childId => 0, childId => 0,
@ -699,7 +706,7 @@ sub onInternalMsg {
if ($type == I_HEARTBEAT_RESPONSE) { if ($type == I_HEARTBEAT_RESPONSE) {
RemoveInternalTimer($hash,"MYSENSORS::Start"); ## Reset reconnect because timeout was not reached RemoveInternalTimer($hash,"MYSENSORS::Start"); ## Reset reconnect because timeout was not reached
readingsSingleUpdate($hash, "heartbeat", "alive", 0); readingsSingleUpdate($hash, 'heartbeat', 'alive', 0);
if ($client = matchClient($hash,$msg)){ if ($client = matchClient($hash,$msg)){
return if IsDisabled( $client->{NAME} ); return if IsDisabled( $client->{NAME} );
MYSENSORS::DEVICE::onInternalMessage($client,$msg) MYSENSORS::DEVICE::onInternalMessage($client,$msg)
@ -794,25 +801,34 @@ sub onAcknowledge {
sub getFirmwareTypes { sub getFirmwareTypes {
my $hash = shift; my $hash = shift;
my $mode = shift // 0;
my $filename = shift // AttrVal($hash->{NAME}, 'OTA_firmwareConfig', undef);
my $name = $hash->{NAME}; my $name = $hash->{NAME};
return @{$hash->{'.fwList'}} if !$mode && defined $hash->{'.fwList'};
return 'OTA_firmwareConfig_not_set_in_gateway' if !$mode && !defined $hash->{'.fwList'};
my @fwTypes = (); my @fwTypes = ();
my $filename = AttrVal($name, "OTA_firmwareConfig", undef);
if (defined($filename)) { if (defined($filename)) {
my ($err, @lines) = FileRead({FileName => "./FHEM/firmware/" . $filename, my ($err, @lines) = FileRead({FileName => "./FHEM/firmware/$filename",
ForceType => "file"}); ForceType => 'file'});
if (defined($err) && $err) { if ( defined $err && $err ) {
Log3($name, 2, "$name: could not read MySensor firmware configuration file - $err"); Log3($name, 2, "$name: could not read MySensor firmware configuration file - $err");
} else { return $err if $mode eq 'set' && $init_done;
for (my $i = 0; $i < @lines ; $i++) { return @fwTypes;
chomp(my $row = $lines[$i]); }
if (index($row, "#") != 0) { for (@lines) {
my @tokens = split(",", $row); chomp($_);
push(@fwTypes, $tokens[0]); if (index($_, "#") != 0) {
} my @tokens = split m{,}xms, $_;
push @fwTypes, $tokens[0] if looks_like_number($tokens[0]);
} }
} }
$hash->{'.fwList'} = [@fwTypes];
} }
delete $hash->{'.fwList'} if !@fwTypes;
Log3($name, 5, "$name: getFirmwareTypes - list contains: @fwTypes"); Log3($name, 5, "$name: getFirmwareTypes - list contains: @fwTypes");
return if $mode eq 'set' && @fwTypes;
return 'file contains no valid data' if $mode eq 'set' && !@fwTypes;
return @fwTypes; return @fwTypes;
} }
@ -820,22 +836,22 @@ sub getLatestFirmware {
my $hash = shift; my $hash = shift;
my $type = shift // return; my $type = shift // return;
my $name = $hash->{NAME}; my $name = $hash->{NAME};
my $cfgfilename = AttrVal($name, "OTA_firmwareConfig", undef); my $cfgfilename = AttrVal($name, 'OTA_firmwareConfig', undef);
my $version = undef; my $version = undef;
$name = undef; $name = undef;
my $filename = undef; my $filename = undef;
if (defined($cfgfilename)) { if (defined($cfgfilename)) {
my ($err, @lines) = FileRead({FileName => "./FHEM/firmware/" . $cfgfilename, my ($err, @lines) = FileRead({FileName => "./FHEM/firmware/$cfgfilename",
ForceType => "file"}); ForceType => 'file'});
if (defined($err) && $err) { if (defined($err) && $err) {
Log3($name, 2, "$name: could not read MySensor firmware configuration file - $err"); Log3($name, 2, "$name: could not read MySensor firmware configuration file - $err");
} else { } else {
for (my $i = 0; $i < @lines ; $i++) { for (@lines) {
chomp(my $row = $lines[$i]); chomp($_);
if (index($row, "#") != 0) { if (index($_, '#') != 0) {
my @tokens = split(",", $row); my @tokens = split m{,}xms, $_;
if ($tokens[0] eq $type) { if ($tokens[0] eq $type) {
if ((not defined $version) || ($tokens[2] > $version)) { if ( !defined $version || $tokens[2] > $version ) {
$name = $tokens[1]; $name = $tokens[1];
$version = $tokens[2]; $version = $tokens[2];
$filename = $tokens[3]; $filename = $tokens[3];
@ -916,12 +932,10 @@ sub matchChan76GWClient {
if ( defined( $defs{$d} ) if ( defined( $defs{$d} )
&& defined( $defs{$d}{radioId} ) && defined( $defs{$d}{radioId} )
&& $defs{$d}{radioId} == $radioId ) { && $defs{$d}{radioId} == $radioId ) {
#my $clientname = $defs{$d}->{NAME}; $found = $defs{$d} if AttrVal($d,'OTA_Chan76_IODev','') eq $name;
#$found = $defs{$d} if AttrVal($clientname,"OTA_Chan76_IODev","") eq
$found = $defs{$d} if AttrVal($d,"OTA_Chan76_IODev","") eq $name;
} }
} }
Log3($hash, 4, "$name: matched firmware config request to IO-name $found->{NAME}") if $found; Log3($hash, 4, "$name: matched firmware config request to IO-name $found->{NAME}") if $found;
return $found; return $found;
} }
@ -939,6 +953,7 @@ sub parseMsg {
(?<type> [0-9]{1,2}); (?<type> [0-9]{1,2});
(?<payload> .*) (?<payload> .*)
\z}xms); \z}xms);
#my $payload = $+{payload} // q{};
return { return {
radioId => $+{nodeid}, # docs speak of "nodeId" radioId => $+{nodeid}, # docs speak of "nodeId"
@ -1014,18 +1029,19 @@ __END__
<a id="MYSENSORS-set"></a> <a id="MYSENSORS-set"></a>
<h4>Set</h4> <h4>Set</h4>
<ul> <ul>
<li> <li><a id="MYSENSORS-set-connect"></a>
<p><a id="MYSENSORS-set-connect"></a><b>connect</b></p> <p><b>connect</b></p>
<p><code>set &lt;name&gt; connect</code></p> <p><code>set &lt;name&gt; connect</code></p>
<p>(re-)connects the MYSENSORS-device to the MYSENSORS-gateway</p> <p>(re-)connects the MYSENSORS-device to the MYSENSORS-gateway</p>
<p>Can also be used to reload the <i>OTA_firmwareConfig</i> file after editing.</p>
</li> </li>
<li> <li><a id="MYSENSORS-set-disconnect"></a>
<p><a id="MYSENSORS-set-disconnect"></a><b>disconnect</b></p> <p><b>disconnect</b></p>
<p><code>set &lt;name&gt; disconnect</code></p> <p><code>set &lt;name&gt; disconnect</code></p>
<p>disconnects the MYSENSORS-device from the MYSENSORS-gateway</p> <p>disconnects the MYSENSORS-device from the MYSENSORS-gateway</p>
</li> </li>
<li> <li><a id="MYSENSORS-set-inclusion-mode"></a>
<p><a id="MYSENSORS-set-inclusion-mode"></a><b>inclusion-mode</b></p> <p><b>inclusion-mode</b></p>
<p><code>set &lt;name&gt; inclusion-mode on|off</code></p> <p><code>set &lt;name&gt; inclusion-mode on|off</code></p>
<p>turns the gateways inclusion-mode on or off</p> <p>turns the gateways inclusion-mode on or off</p>
</li> </li>
@ -1034,26 +1050,26 @@ __END__
<a id="MYSENSORS-attr"></a> <a id="MYSENSORS-attr"></a>
<h4>Attributes</h4> <h4>Attributes</h4>
<ul> <ul>
<li> <li><a id="MYSENSORS-attr-autocreate"></a>
<p><a id="MYSENSORS-attr-autocreate"></a><b>autocreate</b></p> <p><b>autocreate</b></p>
<p><code>attr &lt;name&gt; autocreate</code></p> <p><code>attr &lt;name&gt; autocreate</code></p>
<p>enables auto-creation of MYSENSOR_DEVICE-devices on receival of presentation-messages</p> <p>enables auto-creation of MYSENSOR_DEVICE-devices on receival of presentation-messages</p>
</li> </li>
<li> <li><a id="MYSENSORS-attr-requestAck"></a>
<p><a id="MYSENSORS-attr-requestack"></a><b>requestAck</b></p> <p><b>requestAck</b></p>
<p><code>attr &lt;name&gt; requestAck</code></p> <p><code>attr &lt;name&gt; requestAck</code></p>
<p>request acknowledge from nodes.</p> <p>request acknowledge from nodes.</p>
<p>if set the Readings of nodes are updated not before requested acknowledge is received<br> <p>if set the Readings of nodes are updated not before requested acknowledge is received<br>
if not set the Readings of nodes are updated immediatly (not awaiting the acknowledge).</p> if not set the Readings of nodes are updated immediatly (not awaiting the acknowledge).</p>
<p>May also be configured for individual nodes if not set for gateway.</p> <p>May also be configured for individual nodes if not set for gateway.</p>
</li> </li>
<li> <li><a id="MYSENSORS-attr-first-sensorid"></a>
<p><a id="MYSENSORS-attr-first-sensorid"></a><b>first-sensorid</b></p> <p><b>first-sensorid</b></p>
<p><code>attr &lt;name&gt; first-sensorid &lt;number &lt;h;255&gt;&gt;</code></p> <p><code>attr &lt;name&gt; first-sensorid &lt;number &lt; 255&gt;</code></p>
<p>configures the lowest node-id assigned to a mysensor-node on request (defaults to 20)</p> <p>configures the lowest node-id assigned to a mysensor-node on request (defaults to 20)</p>
</li> </li>
<li> <li><a id="MYSENSORS-attr-OTA_firmwareConfig"></a>
<p><a id="MYSENSORS-attr-ota_firmwareconfig"></a><b>OTA_firmwareConfig</b></p> <p><b>OTA_firmwareConfig</b></p>
<p><code>attr &lt;name&gt; OTA_firmwareConfig &lt;filename&gt;</code></p> <p><code>attr &lt;name&gt; OTA_firmwareConfig &lt;filename&gt;</code></p>
<p>specifies a configuration file for the <a href="https://www.mysensors.org/about/fota">FOTA</a> <p>specifies a configuration file for the <a href="https://www.mysensors.org/about/fota">FOTA</a>
(firmware over the air - wireless programming of the nodes) configuration. It must be stored (firmware over the air - wireless programming of the nodes) configuration. It must be stored
@ -1074,6 +1090,7 @@ __END__
<dt><code>Comments</code></dt> <dt><code>Comments</code></dt>
<dd>a description / comment for the firmware</dd> <dd>a description / comment for the firmware</dd>
</dl> </dl>
<p>Note: Firmware config file by default only is read at startup. If you change it later, just issue a <i>connect</i> command to update also Internal values.</p>
</li> </li>
</ul> </ul>

View File

@ -231,15 +231,15 @@ sub Define {
my $hash = shift; my $hash = shift;
my $def = shift // return; my $def = shift // return;
return $@ unless ( FHEM::Meta::SetInternals($hash) ); return $@ unless ( FHEM::Meta::SetInternals($hash) );
my ($name, $type, $radioId) = split m{\s+}xms, $def; # split("[ \t]+", $def); my ($name, $type, $radioId) = split m{\s+}xms, $def;
return "requires 1 parameter!" if (!defined $radioId || $radioId eq ""); return 'requires 1 parameter!' if (!defined $radioId || $radioId eq '');
$hash->{radioId} = $radioId; $hash->{radioId} = $radioId;
$hash->{sets} = { $hash->{sets} = {
'time' => "noArg", time => 'noArg',
'reboot' => "noArg", reboot => 'noArg',
'clear' => "noArg", clear => 'noArg',
'flash' => "noArg", flash => 'noArg',
'fwType' => "", fwType => '',
}; };
$hash->{ack} = 0; $hash->{ack} = 0;
@ -261,17 +261,17 @@ sub Set {
return "At least one parameter is needed!" if !defined $command; return "At least one parameter is needed!" if !defined $command;
return "Node is disabled!" if IsDisabled( $hash->{NAME} ); return "Node is disabled!" if IsDisabled( $hash->{NAME} );
if(!defined($hash->{sets}->{$command})) { if(!defined($hash->{sets}->{$command})) {
$hash->{sets}->{fwType} = join(",", MYSENSORS::getFirmwareTypes($hash->{IODev})); $hash->{sets}->{fwType} = join q{,}, MYSENSORS::getFirmwareTypes( $hash->{IODev} );
my $list = join(" ", map { my $list = join( q{ }, map {
$hash->{sets}->{$_} ne "" ? "$_:$hash->{sets}->{$_}" $hash->{sets}->{$_} ne '' ? "$_:$hash->{sets}->{$_}"
: $_ : $_
} sort keys %{$hash->{sets}}); } sort keys %{$hash->{sets}});
$hash->{sets}->{fwType} = ""; $hash->{sets}->{fwType} = q{};
return SetExtensions($hash, $list, $name, $command, @values); return SetExtensions($hash, $list, $name, $command, @values);
} }
if ($command =~ m{\A(time|reboot|clear|flash|fwType)\z}xms) { if ($command =~ m{\A(time|reboot|clear|flash|fwType)\z}xms) {
if ($command eq "time") { if ($command eq 'time') {
my $t = timegm_nocheck(localtime(time)); my $t = timegm_nocheck(localtime(time));
return sendClientMessage($hash, return sendClientMessage($hash,
childId => 255, childId => 255,
@ -282,8 +282,8 @@ sub Set {
); );
} }
if ($command eq "reboot") { if ($command eq 'reboot') {
(AttrVal($name, "OTA_BL_Type", 0) or ReadingsVal($name, "BL_VERSION", 0)) (AttrVal($name, 'OTA_BL_Type', 0) or ReadingsVal($name, 'BL_VERSION', 0))
? return sendClientMessage($hash, ? return sendClientMessage($hash,
childId => 255, childId => 255,
cmd => C_INTERNAL, cmd => C_INTERNAL,
@ -293,7 +293,7 @@ sub Set {
: return; : return;
} }
if ($command eq "clear") { if ($command eq 'clear') {
Log3 ($name,3,"MYSENSORS_DEVICE $name: clear"); Log3 ($name,3,"MYSENSORS_DEVICE $name: clear");
return sendClientMessage($hash, return sendClientMessage($hash,
childId => 255, childId => 255,
@ -304,25 +304,25 @@ sub Set {
); );
} }
if ($command eq "flash") { if ($command eq 'flash') {
my $blVersion = ReadingsVal($name, "BL_VERSION", ""); my $blVersion = ReadingsVal($name, 'BL_VERSION', '');
my $blType = AttrVal($name, "OTA_BL_Type", ""); my $blType = AttrVal($name, 'OTA_BL_Type', '');
my $fwType = ReadingsNum($name, "FW_TYPE", -1); my $fwType = ReadingsNum($name, 'FW_TYPE', -1);
if ($fwType == -1) { if ($fwType == -1) {
Log3 ($name,3,"Firmware type not defined (FW_TYPE) for $name, update not started"); Log3 ($name,3,"Firmware type not defined (FW_TYPE) for $name, update not started");
return "$name: Firmware type not defined (FW_TYPE)"; return "$name: Firmware type not defined (FW_TYPE)";
} }
if ($blVersion eq "3.0" or $blType eq "Optiboot") { if ($blVersion eq '3.0' or $blType eq 'Optiboot') {
Log3 ($name,4,"Startet flashing Firmware: Optiboot method"); Log3 ($name,4,'Startet flashing Firmware: Optiboot method');
return flashFirmware($hash, $fwType); return flashFirmware($hash, $fwType);
} }
if ($blType eq "MYSBootloader") { if ($blType eq 'MYSBootloader') {
$hash->{OTA_requested} = 1; $hash->{OTA_requested} = 1;
Log3 ($name,4,"Send reboot command to MYSBootloader node to start update"); Log3 ($name,4,"Send reboot command to MYSBootloader node to start update");
return sendClientMessage($hash, return sendClientMessage($hash,
childId => 255, childId => 255,
cmd => C_INTERNAL, cmd => C_INTERNAL,
ack => 1, ack => 0,
subType => I_REBOOT subType => I_REBOOT
); );
} else { } else {
@ -335,7 +335,8 @@ sub Set {
if ($command eq 'fwType') { if ($command eq 'fwType') {
my $type = shift @values // return; my $type = shift @values // return;
return "fwType must be numeric, but got >$type<." if ($type !~ m{^[0-9]{2,20}$}xms); return "fwType must be numeric, but got >$type<." if ($type !~ m{^[0-9]{2,20}$}xms);
return readingsSingleUpdate($hash, 'FW_TYPE', $type, 1); readingsSingleUpdate($hash, 'FW_TYPE', $type, 1);
return;
} }
} }
@ -1352,38 +1353,38 @@ __END__
<a id="MYSENSORS_DEVICE-set"></a> <a id="MYSENSORS_DEVICE-set"></a>
<h4>Set</h4> <h4>Set</h4>
<ul> <ul>
<li> <li><a id="MYSENSORS_DEVICE-set-attrTemplate"></a>
<p><a id="MYSENSORS_DEVICE-set-update"></a><b>AttrTemplate</b></p> <p><b>AttrTemplate</b></p>
<p>Helps to easily configure your devices. Just get a list of all available attrTremplates by issuing<br> <p>Helps to easily configure your devices. Just get a list of all available attrTremplates by issuing<br>
<code>set &lt;name&gt; attrTemplate ?</code></p> <code>set &lt;name&gt; attrTemplate ?</code></p>
<p>Have a look at the descriptions and choose a suitable one. Then use the drop-down list and click "set" or use<br> <p>Have a look at the descriptions and choose a suitable one. Then use the drop-down list and click "set" or use<br>
<code>set &lt;name&gt; attrTemplate A_02a_atmospheric_pressure</code></p> <code>set &lt;name&gt; attrTemplate A_02a_atmospheric_pressure</code></p>
</li> </li>
<li> <li><a id="MYSENSORS_DEVICE-set-clear"></a>
<p><a id="MYSENSORS_DEVICE-set-clear"></a><b>clear</b></p> <p><b>clear</b></p>
<p><code>set &lt;name&gt; clear</code></p> <p><code>set &lt;name&gt; clear</code></p>
<p>clears MySensors EEPROM area and reboot (i.e. &quot;factory&quot; reset) - requires MY_SPECIAL_DEBUG</p> <p>clears MySensors EEPROM area and reboot (i.e. &quot;factory&quot; reset) - requires MY_SPECIAL_DEBUG</p>
</li> </li>
<li> <li><a id="MYSENSORS_DEVICE-set-flash"></a>
<p><a id="MYSENSORS_DEVICE-set-flash"></a><b>flash</b></p> <p><b>flash</b></p>
<p><code>set &lt;name&gt; flash</code></p> <p><code>set &lt;name&gt; flash</code></p>
<p>Checks whether a newer firmware version is available. If a newer firmware version is <p>Checks whether a newer firmware version is available. If a newer firmware version is
available the flash procedure is started. The sensor node must support FOTA for available the flash procedure is started. The sensor node must support FOTA for
this.</p> this.</p>
</li> </li>
<li> <li><a id="MYSENSORS_DEVICE-set-fwType"></a>
<p><a id="MYSENSORS_DEVICE-set-fwType"></a><b>fwType</b></p> <p><b>fwType</b></p>
<p><code>set &lt;name&gt; fwType &lt;value&gt;</code></p> <p><code>set &lt;name&gt; fwType &lt;value&gt;</code></p>
<p>assigns a firmware type to this node (must be a numeric value in the range 0 .. 65536).<br> <p>assigns a firmware type to this node (must be a numeric value in the range 0 .. 65536).<br>
Should be contained in the <a href="#MYSENSORS-attr-ota_firmwareconfig">FOTA configuration file</a>.</p> Should be contained in the <a href="#MYSENSORS-attr-ota_firmwareconfig">FOTA configuration file</a></p>. <p>Note: Firmware config file by default only is read at startup. If you change it later, just issue a <i>connect</i> command to the GW to update also Internal values.</p>
</li> </li>
<li> <li><a id="MYSENSORS_DEVICE-set-time"></a>
<p><a id="MYSENSORS_DEVICE-set-time"></a><b>time</b></p> <p><b>time</b></p>
<p><code>set &lt;name&gt; time</code></p> <p><code>set &lt;name&gt; time</code></p>
<p>sets time for nodes (that support it)</p> <p>sets time for nodes (that support it)</p>
</li> </li>
<li> <li><a id="MYSENSORS_DEVICE-set-reboot"></a>
<p><a id="MYSENSORS_DEVICE-set-reboot"></a><b>reboot</b></p> <p><b>reboot</b></p>
<p><code>set &lt;name&gt; reboot</code></p> <p><code>set &lt;name&gt; reboot</code></p>
<p>reboots a node (requires a bootloader that supports it).<br/>Attention: Nodes that run the standard arduino-bootloader will enter a bootloop!<br/>Dis- and reconnect the nodes power to restart in this case.</p> <p>reboots a node (requires a bootloader that supports it).<br/>Attention: Nodes that run the standard arduino-bootloader will enter a bootloop!<br/>Dis- and reconnect the nodes power to restart in this case.</p>
</li> </li>
@ -1392,20 +1393,20 @@ __END__
<a id="MYSENSORS_DEVICE-get"></a> <a id="MYSENSORS_DEVICE-get"></a>
<h4>Get</h4> <h4>Get</h4>
<ul> <ul>
<li> <li><a id="MYSENSORS_DEVICE-get-Extended_DEBUG"></a>
<p><a id="MYSENSORS_DEVICE-get-extended_debug"></a><b>Extended_DEBUG</b></p> <p><b>Extended_DEBUG</b></p>
<p><code>get &lt;name&gt; Extended_DEBUG</code></p> <p><code>get &lt;name&gt; Extended_DEBUG</code></p>
<p>requires MY_SPECIAL_DEBUG<br> <p>requires MY_SPECIAL_DEBUG<br>
retrieves the CPU frequency, CPU voltage and free memory of the sensor</p> retrieves the CPU frequency, CPU voltage and free memory of the sensor</p>
</li> </li>
<li> <li><a id="MYSENSORS_DEVICE-get-ReadingsFromComment"></a>
<p><a id="MYSENSORS_DEVICE-get-readingsfromcomment"></a><b>ReadingsFromComment</b></p> <p><b>ReadingsFromComment</b></p>
<p><code>get &lt;name&gt; ReadingsFromComment</code></p> <p><code>get &lt;name&gt; ReadingsFromComment</code></p>
<p>rebuild reding names from comments of presentation messages if available<br> <p>rebuild reding names from comments of presentation messages if available<br>
After issuing this get check the log for changes.</p> After issuing this get check the log for changes.</p>
</li> </li>
<li> <li><a id="MYSENSORS_DEVICE-get-RSSI"></a>
<p><a id="MYSENSORS_DEVICE-get-rssi"></a><b>RSSI</b></p> <p><b>RSSI</b></p>
<p><code>get &lt;name&gt; RSSI</code></p> <p><code>get &lt;name&gt; RSSI</code></p>
<p>requires MY_SIGNAL_REPORT_ENABLED, not supported by all transportation layers<br> <p>requires MY_SIGNAL_REPORT_ENABLED, not supported by all transportation layers<br>
delievers a set of Signal Quality information.</p> delievers a set of Signal Quality information.</p>
@ -1415,38 +1416,38 @@ __END__
<a id="MYSENSORS_DEVICE-attr"></a> <a id="MYSENSORS_DEVICE-attr"></a>
<h4>Attributes</h4> <h4>Attributes</h4>
<ul> <ul>
<li> <li><a id="MYSENSORS_DEVICE-attr-config"></a>
<p><a id="MYSENSORS_DEVICE-attr-config"></a><b>config</b></p> <p><b>config</b></p>
<p><code>attr &lt;name&gt; config [&lt;M|I&gt;]</code></p> <p><code>attr &lt;name&gt; config [&lt;M|I&gt;]</code></p>
<p>configures metric (M) or inch (I). Defaults to 'M'</p> <p>configures metric (M) or inch (I). Defaults to 'M'</p>
</li> </li>
<li> <li><a id="MYSENSORS_DEVICE-attr-OTA_autoUpdate"></a>
<p><a id="MYSENSORS_DEVICE-attr-ota_autoUpdate"></a><b>OTA_autoUpdate</b></p> <p><b>OTA_autoUpdate</b></p>
<p><code>attr &lt;name&gt; OTA_autoUpdate [&lt;0|1&gt;]</code></p> <p><code>attr &lt;name&gt; OTA_autoUpdate [&lt;0|1&gt;]</code></p>
<p>specifies whether an automatic update of the sensor node should be performed (1) during startup of the node or not (0). Defaults to 0</p> <p>specifies whether an automatic update of the sensor node should be performed (1) during startup of the node or not (0). Defaults to 0</p>
</li> </li>
<li> <li><a id="MYSENSORS_DEVICE-attr-setCommands">
<p><a id="MYSENSORS_DEVICE-attr-setcommands"></a><b>setCommands</b></p> <p></a><b>setCommands</b></p>
<p><code>attr &lt;name&gt; setCommands [&lt;command:reading:value&gt;]*</code></p> <p><code>attr &lt;name&gt; setCommands [&lt;command:reading:value&gt;]*</code></p>
<p>configures one or more commands that can be executed by set.</p> <p>configures one or more commands that can be executed by set.</p>
<p>e.g.:<br> <p>e.g.:<br>
<code>attr &lt;name&gt; setCommands on:switch_1:on off:switch_1:off</code></p> <code>attr &lt;name&gt; setCommands on:switch_1:on off:switch_1:off</code></p>
<p>if list of commands contains both 'on' and 'off' <a href="#setExtensions">set extensions</a> are supported</p> <p>if list of commands contains both 'on' and 'off' <a href="#setExtensions">set extensions</a> are supported</p>
</li> </li>
<li> <li><a id="MYSENSORS_DEVICE-attr-setReading_ " data-pattern="setReading_.*"></a>
<p><a id="MYSENSORS_DEVICE-attr-setreading"></a><b>setReading_&lt;reading&gt;</b></p> <p><b>setReading_&lt;reading&gt;</b></p>
<p><code>attr &lt;name&gt; setReading_&lt;reading&gt; [&lt;value&gt;]*</code></p> <p><code>attr &lt;name&gt; setReading_&lt;reading&gt; [&lt;value&gt;]*</code></p>
<p>configures a reading that can be modified by set-command</p> <p>configures a reading that can be modified by set-command</p>
<p>e.g.:<br> <p>e.g.:<br>
<code>attr &lt;name&gt; setReading_switch_1 on,off</code></p> <code>attr &lt;name&gt; setReading_switch_1 on,off</code></p>
</li> </li>
<li> <li><a id="MYSENSORS_DEVICE-attr-setExtensionsEvent"></a>
<p><a id="MYSENSORS_DEVICE-attr-setextensionsevent"></a><b>setExtensionsEvent</b></p> <p><b>setExtensionsEvent</b></p>
<p><code>attr &lt;name&gt; setExtensionsEvent</code></p> <p><code>attr &lt;name&gt; setExtensionsEvent</code></p>
<p>If set, the event will contain the command implemented by SetExtensions (e.g. on-for-timer 10), else the executed command (e.g. on).</p> <p>If set, the event will contain the command implemented by SetExtensions (e.g. on-for-timer 10), else the executed command (e.g. on).</p>
</li> </li>
<li> <li><a id="MYSENSORS_DEVICE-attr-mapReading_" data-pattern="mapReading_.*"></a>
<p><a id="MYSENSORS_DEVICE-attr-mapreading"></a><b>mapReading_&lt;reading&gt;</b></p> <p><b>mapReading_&lt;reading&gt;</b></p>
<p><code>attr &lt;name&gt; mapReading_&lt;reading&gt; &lt;childId&gt; &lt;readingtype&gt; [&lt;value&gt;:&lt;mappedvalue&gt;]*</code></p> <p><code>attr &lt;name&gt; mapReading_&lt;reading&gt; &lt;childId&gt; &lt;readingtype&gt; [&lt;value&gt;:&lt;mappedvalue&gt;]*</code></p>
<p>configures the reading-name for a given childId and sensortype</p> <p>configures the reading-name for a given childId and sensortype</p>
<p>e.g.:<br> <p>e.g.:<br>
@ -1454,39 +1455,40 @@ __END__
<code>attr xxx mapReading_leftwindow 10 status 1:closed 0:open</code></p> <code>attr xxx mapReading_leftwindow 10 status 1:closed 0:open</code></p>
<p>See also mapReadingType for setting defaults for types without predefined defaults</p> <p>See also mapReadingType for setting defaults for types without predefined defaults</p>
</li> </li>
<li> <li><a id="MYSENSORS_DEVICE-attr-requestAck"></a>
<p><a id="MYSENSORS_DEVICE-attr-requestack"></a><b>requestAck</b></p> <p><b>requestAck</b></p>
<p><code>attr &lt;name&gt; requestAck</code></p> <p><code>attr &lt;name&gt; requestAck</code></p>
<p>request acknowledge from nodes.<br> <p>request acknowledge from nodes.<br>
if set the Readings of nodes are updated not before requested acknowledge is received<br> if set the Readings of nodes are updated not before requested acknowledge is received<br>
if not set the Readings of nodes are updated immediatly (not awaiting the acknowledge).<br> if not set the Readings of nodes are updated immediatly (not awaiting the acknowledge).<br>
May also be configured on the gateway for all nodes at once</p> May also be configured on the gateway for all nodes at once</p>
</li> </li>
<li> <li><a id="MYSENSORS_DEVICE-attr-mapReadingType_" data-pattern="mapReadingType_.*"></a>
<p><a id="MYSENSORS_DEVICE-attr-mapreadingtype"></a><b>mapReadingType_&lt;reading&gt;</b></p> <p><b>mapReadingType_&lt;reading&gt;</b></p>
<p><code>attr &lt;name&gt; mapReadingType_&lt;reading&gt; &lt;new reading name&gt; [&lt;value&gt;:&lt;mappedvalue&gt;]*</code></p> <p><code>attr &lt;name&gt; mapReadingType_&lt;reading&gt; &lt;new reading name&gt; [&lt;value&gt;:&lt;mappedvalue&gt;]*</code></p>
<p>configures reading type names that should be used instead of technical names</p> <p>configures reading type names that should be used instead of technical names</p>
<p>e.g.:<br> <p>e.g.:<br>
<code>attr xxx mapReadingType_LIGHT switch 0:on 1:off</code></p> <code>attr xxx mapReadingType_LIGHT switch 0:on 1:off</code></p>
<p>to be used for mysensor Variabletypes that have no predefined defaults (yet)</p> <p>to be used for mysensor Variabletypes that have no predefined defaults (yet)</p>
</li> </li>
<li> <li><a id="MYSENSORS_DEVICE-attr-OTA_BL_Type"></a>
<p><a id="MYSENSORS_DEVICE-attr-ota_bl_type"></a><b>OTA_BL_Type</b></p> <p><b>OTA_BL_Type</b></p>
<p><code>attr &lt;name&gt; OTA_BL_Type &lt;either Optiboot or MYSBootloader&gt;*</code></p> <p><code>attr &lt;name&gt; OTA_BL_Type &lt;either Optiboot or MYSBootloader&gt;*</code></p>
<p>For other bootloaders than Optiboot V3.0 OTA updates will only work if bootloader type is specified - MYSBootloader will reboot node if firmware update is started, so make sure, node will really recover</p> <p>For other bootloaders than Optiboot V3.0 OTA updates will only work if bootloader type is specified - MYSBootloader will reboot node if firmware update is started, so make sure, node will really recover</p>
</li> </li>
<li> <li><a id="MYSENSORS_DEVICE-attr-OTA_Chan76_IODev">
<p><a id="MYSENSORS_DEVICE-attr-ota_chan76_iodev"></a><b>OTA_Chan76_IODev</b></p> <p></a><b>OTA_Chan76_IODev</b></p>
<p><code>attr &lt;name&gt; OTA_Chan76_IODev </code></p> <p><code>attr &lt;name&gt; OTA_Chan76_IODev </code></p>
<p>As MYSBootloader per default uses nRF24 channel 76, you may specify a different IODev for OTA data using channel 76</p> <p>As MYSBootloader per default uses nRF24 channel 76, you may specify a different IODev for OTA data using channel 76</p>
</li> </li>
<li> <li><a id="MYSENSORS_DEVICE-attr-timeoutAck"></a>
<p><a id="MYSENSORS_DEVICE-attr-timeoutack"></a><b>timeoutAck</b></p> <p><b>timeoutAck</b></p>
<p><code>attr &lt;name&gt; timeoutAck &lt;time in seconds&gt;*</code></p> <p><code>attr &lt;name&gt; timeoutAck &lt;time in seconds&gt;*</code></p>
<p>configures timeout to set device state to NACK in case not all requested acks are received</p> <p>configures timeout to set device state to NACK in case not all requested acks are received</p>
</li> </li>
<li>
<p><a id="MYSENSORS_DEVICE-attr-timeoutalive"></a><b>timeoutAlive</b></p> <li><a id="MYSENSORS_DEVICE-attr-timeoutAlive"></a>
<p><b>timeoutAlive</b></p>
<p><code>attr &lt;name&gt; timeoutAlive &lt;time in seconds&gt;*</code></p> <p><code>attr &lt;name&gt; timeoutAlive &lt;time in seconds&gt;*</code></p>
<p>configures timeout to set device state to alive or dead. If messages from node are received within timout spec, state will be alive, otherwise dead. If state is NACK (in case timeoutAck is also set), state will only be changed to alive, if there are no outstanding messages to be sent.</p> <p>configures timeout to set device state to alive or dead. If messages from node are received within timout spec, state will be alive, otherwise dead. If state is NACK (in case timeoutAck is also set), state will only be changed to alive, if there are no outstanding messages to be sent.</p>
</li> </li>