diff --git a/fhem/CHANGED b/fhem/CHANGED index 1b51aacd5..be1c634dc 100644 --- a/fhem/CHANGED +++ b/fhem/CHANGED @@ -1,6 +1,5 @@ # 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. - - feature: 10_MYSENSORS_DEVICE: heartbeat, alive check, sleep and RSSI - change: 74_AMADtasker: AMAD Taskerproject change to new battery states - feature: 49_SSCamSTRM: new attr hideDisplayName regarding to Forum #88667 - bugfix: 49_SSCam: global vars diff --git a/fhem/FHEM/10_MYSENSORS_DEVICE.pm b/fhem/FHEM/10_MYSENSORS_DEVICE.pm index 1d536350f..8bcc6a7a5 100755 --- a/fhem/FHEM/10_MYSENSORS_DEVICE.pm +++ b/fhem/FHEM/10_MYSENSORS_DEVICE.pm @@ -20,7 +20,7 @@ # You should have received a copy of the GNU General Public License # along with fhem. If not, see . # -# $Id$id$ +# $Id$ # ############################################## @@ -28,10 +28,7 @@ use strict; use warnings; my %gets = ( - # "version" => 1, - "heartbeat" => 1, #request node to send hearbeat, MySensorsCore.cpp L 429 - # "presentation" => 1, #request node to redo presentation, MySensorsCore.cpp L 426 - "RSSI" => 1, #request RSSI values (available only for recent versions, not for all transceiver types + "version" => "", ); sub MYSENSORS_DEVICE_Initialize($) { @@ -42,7 +39,6 @@ sub MYSENSORS_DEVICE_Initialize($) { $hash->{DefFn} = "MYSENSORS::DEVICE::Define"; $hash->{UndefFn} = "MYSENSORS::DEVICE::UnDefine"; $hash->{SetFn} = "MYSENSORS::DEVICE::Set"; - $hash->{GetFn} = "MYSENSORS::DEVICE::Get"; $hash->{AttrFn} = "MYSENSORS::DEVICE::Attr"; $hash->{AttrList} = @@ -274,35 +270,6 @@ sub Set($@) { } } -sub Get($@) { - my ($hash, @a) = @_; - my $type = $hash->{TYPE}; - return "\"get $type\" needs at least one parameter" if(@a < 2); - if(!defined($gets{$a[1]})) { - my @cList = map { $_ =~ m/^(file|raw)$/ ? $_ : "$_:noArg" } sort keys %gets; - return "Unknown argument $a[1], choose one of " . join(" ", @cList); - } - my $command = $a[1]; - COMMAND_HANDLER: { - $command eq "version" and do { - sendMessage($hash->{IODev}, radioId => $hash->{radioId}, cmd => C_INTERNAL, ack => 0, subType => I_VERSION); - last; - }; - $command eq "heartbeat" and do { - sendMessage($hash->{IODev}, radioId => $hash->{radioId}, cmd => C_INTERNAL, ack => 0, subType => I_HEARTBEAT_REQUEST); - last; - }; - $command eq "presentation" and do { - sendMessage($hash->{IODev}, radioId => $hash->{radioId}, cmd => C_INTERNAL, ack => 0, subType => I_PRESENTATION); - last; - }; - $command eq "RSSI" and do { - sendMessage($hash->{IODev}, radioId => $hash->{radioId}, cmd => C_INTERNAL, ack => 0, subType => I_SIGNAL_REPORT_REQUEST); - last; - }; - } -} - sub Attr($$$$) { my ($command,$name,$attribute,$value) = @_; @@ -513,7 +480,7 @@ sub onSetMessage($$) { readingsSingleUpdate($hash, $reading, $value, 1); }; Log3 ($hash->{NAME}, 4, "MYSENSORS_DEVICE $hash->{NAME}: ignoring C_SET-message ".GP_Catch($@)) if $@; - refreshInternalMySTimer($hash,"Alive") if $hash->{timeoutAlive}; #deactivate in case of wanted reduction of alive to internal (heartbeat/battery/smartsleep) messages + refreshInternalMySTimer($hash,"Alive") if $hash->{timeoutAlive}; } else { Log3 ($hash->{NAME}, 5, "MYSENSORS_DEVICE $hash->{NAME}: ignoring C_SET-message without payload"); }; @@ -535,199 +502,107 @@ sub onRequestMessage($$) { } sub onInternalMessage($$) { - my ($hash,$msg) = @_; - my $name = $hash->{NAME}; - my $type = $msg->{subType}; - my $typeStr = internalMessageTypeToStr($type); - INTERNALMESSAGE: { - $type == I_BATTERY_LEVEL and do { - # readingsSingleUpdate($hash, "batterylevel", $msg->{payload}, 1); - # Log3 ($name, 3, "MYSENSORS_DEVICE $name: batterylevel is deprecated and will be removed soon, use batteryPercent instead (Forum #87575)"); - readingsSingleUpdate($hash, "batteryPercent", $msg->{payload}, 1); - refreshInternalMySTimer($hash,"Alive") if $hash->{timeoutAlive}; - Log3 ($name, 4, "MYSENSORS_DEVICE $name: batteryPercent $msg->{payload}"); - last; - }; - $type == I_TIME and do { - if ($msg->{ack}) { - Log3 ($name, 4, "MYSENSORS_DEVICE $name: response to time-request acknowledged"); - } else { - sendClientMessage($hash,cmd => C_INTERNAL, childId => 255, subType => I_TIME, payload => time); - Log3 ($name, 4, "MYSENSORS_DEVICE $name: update of time requested"); - } - last; - }; - $type == I_VERSION and do { - $hash->{$typeStr} = $msg->{payload}; - last; - }; - $type == I_ID_REQUEST and do { - $hash->{$typeStr} = $msg->{payload}; - last; - }; - $type == I_ID_RESPONSE and do { - $hash->{$typeStr} = $msg->{payload}; - last; - }; - $type == I_INCLUSION_MODE and do { - $hash->{$typeStr} = $msg->{payload}; - last; - }; - $type == I_CONFIG and do { - if ($msg->{ack}) { - Log3 ($name, 4, "MYSENSORS_DEVICE $name: response to config-request acknowledged"); - } else { - readingsSingleUpdate($hash, "parentId", $msg->{payload}, 1); - sendClientMessage($hash,cmd => C_INTERNAL, childId => 255, subType => I_CONFIG, payload => AttrVal($name,"config","M")); - Log3 ($name, 4, "MYSENSORS_DEVICE $name: respond to config-request, node parentId = " . $msg->{payload}); - } - last; - }; - $type == I_FIND_PARENT and do { - $hash->{$typeStr} = $msg->{payload}; - last; - }; - $type == I_FIND_PARENT_RESPONSE and do { - $hash->{$typeStr} = $msg->{payload}; - last; - }; - $type == I_LOG_MESSAGE and do { - $hash->{$typeStr} = $msg->{payload}; - last; - }; - $type == I_CHILDREN and do { - readingsSingleUpdate($hash, "state", "routingtable cleared", 1); - Log3 ($name, 3, "MYSENSORS_DEVICE $name: routingtable cleared"); - last; - }; - $type == I_SKETCH_NAME and do { - #$hash->{$typeStr} = $msg->{payload}; - readingsSingleUpdate($hash, "SKETCH_NAME", $msg->{payload}, 1); - last; - }; - $type == I_SKETCH_VERSION and do { - #$hash->{$typeStr} = $msg->{payload}; - readingsSingleUpdate($hash, "SKETCH_VERSION", $msg->{payload}, 1); - last; - }; - $type == I_REBOOT and do { - #$hash->{$typeStr} = $msg->{payload}; - last; - }; - $type == I_GATEWAY_READY and do { - $hash->{$typeStr} = $msg->{payload}; - last; - }; - $type == I_REQUEST_SIGNING and do { - $hash->{$typeStr} = $msg->{payload}; - last; - }; - $type == I_GET_NONCE and do { - $hash->{$typeStr} = $msg->{payload}; - last; - }; - $type == I_GET_NONCE_RESPONSE and do { - $hash->{$typeStr} = $msg->{payload}; - last; - }; - $type == I_HEARTBEAT_REQUEST and do { - #$hash->{$typeStr} = $msg->{payload}; - eval { - sendMessage($hash->{IODev},radioId => 0, childId => 0, cmd => C_INTERNAL, ack => 0, subType => I_HEARTBEAT_RESPONSE); - }; - refreshInternalMySTimer($hash,"Alive") if $hash->{timeoutAlive}; - last; - }; - $type == I_PRESENTATION and do { - #$hash->{$typeStr} = $msg->{payload}; - last; - }; - $type == I_DISCOVER_REQUEST and do { - #$hash->{$typeStr} = $msg->{payload}; - last; - }; - $type == I_DISCOVER_RESPONSE and do { - #$hash->{$typeStr} = $msg->{payload}; - last; - }; - $type == I_HEARTBEAT_RESPONSE and do { - readingsSingleUpdate($hash, "heartbeat", "last", 0); - refreshInternalMySTimer($hash,"Alive") if $hash->{timeoutAlive}; - $hash->{$typeStr} = $msg->{payload}; - last; - }; - $type == I_LOCKED and do { - $hash->{$typeStr} = $msg->{payload}; - last; - }; - $type == I_REGISTRATION_REQUEST and do { - $hash->{$typeStr} = $msg->{payload}; - last; - }; - $type == I_REGISTRATION_RESPONSE and do { - $hash->{$typeStr} = $msg->{payload}; - last; - }; - $type == I_DEBUG and do { - $hash->{$typeStr} = $msg->{payload}; - last; - }; - $type == I_SIGNAL_REPORT_REVERSE and do { - #$hash->{$typeStr} = $msg->{payload}; - readingsSingleUpdate($hash, "rssi_DEVICE", $msg->{payload}, 1) if ($msg->{payload} > -256 ); - last; - }; - $type == I_SIGNAL_REPORT_RESPONSE and do { - #$hash->{$typeStr} = $msg->{payload}; - readingsSingleUpdate($hash, "rssi_at_IODev", $msg->{payload}, 1) if ($msg->{payload} > -256 ); - last; - }; - $type == I_PRE_SLEEP_NOTIFICATION and do { - #$hash->{$typeStr} = $msg->{payload}; - readingsSingleUpdate($hash, "nowSleeping", "1", 0); - refreshInternalMySTimer($hash,"Alive") if $hash->{timeoutAlive}; - last; - }; - $type == I_POST_SLEEP_NOTIFICATION and do { - #$hash->{$typeStr} = $msg->{payload}; - readingsSingleUpdate($hash, "nowSleeping", "0", 0); - refreshInternalMySTimer($hash,"Alive") if $hash->{timeoutAlive}; - #here we can send out retained and outstanding messages - $hash->{nexttry} = -1; - MYSENSORS::Timer($hash); - my $retainedMsg; - while (defined($retainedMsg = shift @{$hash->{retainedMessagesForRadioId}})) { - sendClientMessage($hash,$retainedMsg); - }; - last; - }; - } + my ($hash,$msg) = @_; + my $name = $hash->{NAME}; + my $type = $msg->{subType}; + my $typeStr = internalMessageTypeToStr($type); + INTERNALMESSAGE: { + $type == I_BATTERY_LEVEL and do { + readingsSingleUpdate($hash, "batterylevel", $msg->{payload}, 1); + Log3 ($name, 4, "MYSENSORS_DEVICE $name: batterylevel $msg->{payload}"); + last; + }; + $type == I_TIME and do { + if ($msg->{ack}) { + Log3 ($name, 4, "MYSENSORS_DEVICE $name: response to time-request acknowledged"); + } else { + sendClientMessage($hash,cmd => C_INTERNAL, childId => 255, subType => I_TIME, payload => time); + Log3 ($name, 4, "MYSENSORS_DEVICE $name: update of time requested"); + } + last; + }; + $type == I_VERSION and do { + $hash->{$typeStr} = $msg->{payload}; + last; + }; + $type == I_ID_REQUEST and do { + $hash->{$typeStr} = $msg->{payload}; + last; + }; + $type == I_ID_RESPONSE and do { + $hash->{$typeStr} = $msg->{payload}; + last; + }; + $type == I_INCLUSION_MODE and do { + $hash->{$typeStr} = $msg->{payload}; + last; + }; + $type == I_CONFIG and do { + if ($msg->{ack}) { + Log3 ($name, 4, "MYSENSORS_DEVICE $name: response to config-request acknowledged"); + } else { + readingsSingleUpdate($hash, "parentId", $msg->{payload}, 1); + sendClientMessage($hash,cmd => C_INTERNAL, childId => 255, subType => I_CONFIG, payload => AttrVal($name,"config","M")); + Log3 ($name, 4, "MYSENSORS_DEVICE $name: respond to config-request, node parentId = " . $msg->{payload}); + } + last; + }; + $type == I_FIND_PARENT and do { + $hash->{$typeStr} = $msg->{payload}; + last; + }; + $type == I_FIND_PARENT_RESPONSE and do { + $hash->{$typeStr} = $msg->{payload}; + last; + }; + $type == I_LOG_MESSAGE and do { + $hash->{$typeStr} = $msg->{payload}; + last; + }; + $type == I_CHILDREN and do { + readingsSingleUpdate($hash, "state", "routingtable cleared", 1); + Log3 ($name, 3, "MYSENSORS_DEVICE $name: routingtable cleared"); + last; + }; + $type == I_SKETCH_NAME and do { + $hash->{$typeStr} = $msg->{payload}; + readingsSingleUpdate($hash, "SKETCH_NAME", $msg->{payload}, 1); + last; + }; + $type == I_SKETCH_VERSION and do { + $hash->{$typeStr} = $msg->{payload}; + readingsSingleUpdate($hash, "SKETCH_VERSION", $msg->{payload}, 1); + last; + }; + $type == I_REBOOT and do { + $hash->{$typeStr} = $msg->{payload}; + last; + }; + $type == I_GATEWAY_READY and do { + $hash->{$typeStr} = $msg->{payload}; + last; + }; + $type == I_REQUEST_SIGNING and do { + $hash->{$typeStr} = $msg->{payload}; + last; + }; + $type == I_GET_NONCE and do { + $hash->{$typeStr} = $msg->{payload}; + last; + }; + $type == I_GET_NONCE_RESPONSE and do { + $hash->{$typeStr} = $msg->{payload}; + last; + }; + } } sub sendClientMessage($%) { my ($hash,%msg) = @_; $msg{radioId} = $hash->{radioId}; $msg{ack} = $hash->{ack} unless defined $msg{ack}; - unless ($hash->{nowSleeping}) { - sendMessage($hash->{IODev},%msg); - refreshInternalMySTimer($hash,"Ack") if (($hash->{ack} or $hash->{IODev}->{ack}) and $hash->{timeoutAck}); - } else { - #write to queue if node is asleep - my $retainedMessagesForRadioId = $hash->{retainedMessagesForRadioId}->{$msg{radioId}}; - unless (defined $retainedMessagesForRadioId) { - $retainedMessagesForRadioId = { - messages => [], - }; - $hash->{retainedMessagesForRadioId}->{$msg{radioId}} = $retainedMessagesForRadioId; - } - my $messages = $retainedMessagesForRadioId->{messages}; - @$messages = grep { - $_->{childId} != $msg{childId} - or $_->{cmd} != $msg{cmd} - or $_->{subType} != $msg{subType} - } @$messages; - push @$messages,\%msg; - } + sendMessage($hash->{IODev},%msg); + refreshInternalMySTimer($hash,"Ack") if (($hash->{ack} or $hash->{IODev}->{ack}) and $hash->{timeoutAck}) ; } sub rawToMappedReading($$$$) { @@ -865,4 +740,4 @@ sub timeoutMySTimer($) { =end html -=cut \ No newline at end of file +=cut