diff --git a/fhem/FHEM/75_MSG.pm b/fhem/FHEM/75_MSG.pm index 57e3bef91..636de997a 100755 --- a/fhem/FHEM/75_MSG.pm +++ b/fhem/FHEM/75_MSG.pm @@ -59,90 +59,6 @@ sub MSG_Initialize($$) { require "$attr{global}{modpath}/FHEM/msgSchema.pm"; } -######################################## -sub MSG_FindAttrVal($$$$) { - my ( $d, $n, $msgType, $default ) = @_; - $msgType = "" unless ($msgType); - $msgType = ucfirst($msgType); - $n .= $msgType if ( $n =~ /^msg(Contact)$/ ); - - my $g = ( - ( - defined( $modules{msgConfig}{defptr} ) - && $n !~ /^(verbose|msgContact.*)$/ - ) - ? $modules{msgConfig}{defptr}{NAME} - : "" - ); - - return - - # look for direct - AttrVal( - $d, $n, - - # look for indirect - AttrVal( - AttrVal( $d, "msgRecipient$msgType", "" ), - $n, - - # look for indirect, type-independent - AttrVal( - AttrVal( $d, "msgRecipient", "" ), - $n, - - # look for global direct - AttrVal( - $g, $n, - - # look for global indirect - AttrVal( - AttrVal( $g, "msgRecipient$msgType", "" ), - $n, - - # look for global indirect, type-independent - AttrVal( - AttrVal( $g, "msgRecipient", "" ), - $n, - - # default - $default - ) - ) - ) - ) - ) - ); -} - -######################################## -sub MSG_FindReadingsVal($$$$) { - my ( $d, $n, $msgType, $default ) = @_; - $msgType = ucfirst($msgType) if ($msgType); - - return - - # look for direct - ReadingsVal( - $d, $n, - - # look for indirect - ReadingsVal( - AttrVal( $d, "msgRecipient$msgType", "" ), - $n, - - # look for indirect, type-independent - ReadingsVal( - AttrVal( $d, "msgRecipient", "" ), - $n, - - # default - $default - ) - ) - ); -} - ######################################## sub CommandMsg($$;$$) { my ( $cl, $msg, $testMode ) = @_; @@ -480,6 +396,13 @@ s/^[\s\t ]*([!]?(([A-Za-z0-9%+._-])*@([%+a-z0-9A-Z.-]+))[\w,@.!?|:]*)[\s\t ]+// ### /type loop ################################################################ + my @unavailabilityIndicators = ( + "0", "false", + "absent", "disappeared", + "unauthorized", "unavailable", + "unreachable", "disconnected" + ); + my $logDevice; $logDevice = $globalDevName; $logDevice = $device @@ -538,7 +461,7 @@ m/^@?([A-Za-z0-9._]+):([A-Za-z0-9._\-\/@+]*):?([A-Za-z0-9._\-\/@+]*)$/ } # FATAL ERROR: device does not exist - if ( !defined( $defs{$device} ) + if ( !msgConfig_IsDevice($device) && $deviceType eq "device" ) { $loopReturn3 .= "Device $device does not exist\n" @@ -658,7 +581,7 @@ m/^@?([A-Za-z0-9._]+):([A-Za-z0-9._\-\/@+]*):?([A-Za-z0-9._\-\/@+]*)$/ # get device location my $deviceLocation = - MSG_FindReadingsVal( $device, "location", $typeUc, + msgConfig_FindReadingsVal( $device, "location", $typeUc, "" ); my $locationDev = ""; @@ -712,13 +635,6 @@ m/^@?([A-Za-z0-9._]+):([A-Za-z0-9._\-\/@+]*):?([A-Za-z0-9._\-\/@+]*)$/ unless ($err); } - my @availabilityIndicators = ( - "0", "false", - "absent", "disappeared", - "unauthorized", "unavailable", - "unreachable", "disconnected" - ); - foreach my $gatewayDevOr ( split /\|/, $gatewayDevs ) { @@ -732,7 +648,7 @@ m/^@?([A-Za-z0-9._]+):([A-Za-z0-9._\-\/@+]*):?([A-Za-z0-9._\-\/@+]*)$/ } if ( $type[$i] ne "mail" - && !defined( $defs{$gatewayDev} ) + && !msgConfig_IsDevice($gatewayDev) && $deviceType eq "device" ) { $useLocation = 2 @@ -747,29 +663,40 @@ m/^@?([A-Za-z0-9._]+):([A-Za-z0-9._\-\/@+]*):?([A-Za-z0-9._\-\/@+]*)$/ elsif ( $type[$i] ne "mail" && ( - grep { - ReadingsVal( - $gatewayDev, - "presence", - "present" - ) eq $_ - } @availabilityIndicators + ( + grep { + ReadingsVal( + $gatewayDev, + "presence", + "present" + ) eq $_ + } @unavailabilityIndicators + ) - || grep { - ReadingsVal( $gatewayDev, - "state", "present" ) eq - $_ - } @availabilityIndicators + || ( + grep { + ReadingsVal( + $gatewayDev, + "state", + "present" + ) eq $_ + } @unavailabilityIndicators + ) || ( defined( $defs{$gatewayDev} + ) + && defined( + $defs{$gatewayDev} {STATE} ) - && grep { - $defs{$gatewayDev} - {STATE} eq $_ - } @availabilityIndicators + && ( + grep { + $defs{$gatewayDev} + {STATE} eq $_ + } @unavailabilityIndicators + ) ) || ReadingsVal( @@ -812,8 +739,7 @@ m/^@?([A-Za-z0-9._]+):([A-Za-z0-9._\-\/@+]*):?([A-Za-z0-9._\-\/@+]*)$/ ### given device name is already a gateway device itself ### - my $deviceType2 = - defined( $defs{$device} ) ? $defs{$device}{TYPE} : ""; + my $deviceType2 = msgConfig_GetType($device); if ( $gatewayDevs eq "" @@ -1375,17 +1301,58 @@ m/^@?([A-Za-z0-9._]+):([A-Za-z0-9._\-\/@+]*):?([A-Za-z0-9._\-\/@+]*)$/ if ( $type[$i] eq "queue" ) { $routeStatus = "OK_QUEUE"; } + elsif ($type[$i] ne "mail" - && !defined( $defs{$gatewayDev} ) + && !msgConfig_IsDevice($gatewayDev) && $deviceType eq "device" ) { $routeStatus = "UNDEFINED"; } + elsif ( $type[$i] ne "mail" && IsDisabled($gatewayDev) ) { $routeStatus = "DISABLED"; } + + elsif ( + $type[$i] ne "mail" + && ( + ( + grep { + ReadingsVal( $gatewayDev, + "presence", "present" ) eq $_ + } @unavailabilityIndicators + ) + + || ( + grep { + ReadingsVal( $gatewayDev, "state", + "present" ) eq $_ + } @unavailabilityIndicators + ) + + || ( + msgConfig_IsDevice($gatewayDev) + && defined( $defs{$gatewayDev}{STATE} ) + && ( + grep { + $defs{$gatewayDev}{STATE} eq $_ + } @unavailabilityIndicators + ) + ) + + || ReadingsVal( $gatewayDev, "available", + "yes" ) =~ m/^(0|no|false)$/i + + || ReadingsVal( $gatewayDev, "reachable", + "yes" ) =~ m/^(0|no|false)$/i + ) + ) + { + $routeStatus = "UNAVAILABLE"; + } + elsif ( $type[$i] ne "mail" && ( @@ -1395,7 +1362,8 @@ m/^(0|false|absent|disappeared|unauthorized|disconnected|unreachable)$/i || ReadingsVal( $gatewayDev, "state", "present" ) =~ m/^(absent|disappeared|unauthorized|disconnected|unreachable)$/i - || ( $defs{$gatewayDev}{STATE} + || ( msgConfig_IsDevice($gatewayDev) + && defined( $defs{$gatewayDev}{STATE} ) && $defs{$gatewayDev}{STATE} =~ m/^(absent|disappeared|unauthorized|disconnected|unreachable)$/i ) @@ -1408,28 +1376,33 @@ m/^(absent|disappeared|unauthorized|disconnected|unreachable)$/i { $routeStatus = "UNAVAILABLE"; } + elsif ( $type[$i] eq "screen" && ReadingsVal( $gatewayDev, "power", "on" ) =~ m/^(0|off)$/i ) { $routeStatus = "OFF"; } + elsif ($type[$i] eq "audio" && $annState ne "long" && $annState ne "short" ) { $routeStatus = "USER_DISABLED"; } + elsif ( $type[$i] eq "light" && $annState eq "off" ) { $routeStatus = "USER_DISABLED"; } + elsif ($type[$i] ne "push" && $type[$i] ne "mail" && $residentDevPresence eq "absent" ) { $routeStatus = "USER_ABSENT"; } + elsif ($type[$i] ne "push" && $type[$i] ne "mail" && $residentDevState eq "asleep" ) @@ -1485,14 +1458,10 @@ m/^(absent|disappeared|unauthorized|disconnected|unreachable)$/i $routeStatus .= "+QUEUE"; } - my $gatewayType = ( - $type[$i] eq "mail" ? "fhemMsgMail" - : ( - $defs{$gatewayDev}{TYPE} - ? $defs{$gatewayDev}{TYPE} - : "UNDEFINED" - ) - ); + my $gatewayType = + $type[$i] eq "mail" + ? "fhemMsgMail" + : msgConfig_GetType( $gatewayDev, "UNDEFINED" ); my $defTitle = ""; $defTitle = @@ -1935,14 +1904,15 @@ m/^(absent|disappeared|unauthorized|disconnected|unreachable)$/i # add user parameters # if gateway supports parseParams my $gatewayDevType = - defined( $defs{$gatewayDev}{TYPE} ) - ? $defs{$gatewayDev}{TYPE} - : undef; + msgConfig_GetType($gatewayDev); if ( - ref($params) eq "HASH" + $gatewayDevType + && ref($params) eq "HASH" && ( $modules{$gatewayDevType} ->{parseParams} || $modules{$gatewayDevType} + ->{msgParams}{parseParams} + || $modules{$gatewayDevType} ->{'.msgParams'}{parseParams} ) ) { diff --git a/fhem/FHEM/75_msgConfig.pm b/fhem/FHEM/75_msgConfig.pm index 086eeb92c..5965dd1d6 100755 --- a/fhem/FHEM/75_msgConfig.pm +++ b/fhem/FHEM/75_msgConfig.pm @@ -255,9 +255,9 @@ sub msgConfig_Set($@) { $device =~ s/[\s\t-]+/_/g; return "Device $device is already existing but not a dummy device" - if ( defined( $defs{$device} ) && $defs{$device}{TYPE} ne "dummy" ); + if ( msgConfig_IsDevice($device) && msgConfig_GetType($device) ne "dummy" ); - if ( !defined( $defs{$device} ) ) { + if ( !msgConfig_IsDevice($device) ) { $return = fhem( "define $device dummy", 1 ); $return .= "Device $device was created" if ( $return eq "" ); @@ -302,9 +302,9 @@ sub msgConfig_Set($@) { if ( defined( $a[0] ) && $a[0] eq "de" ); return "Device $device is already existing but not a dummy device" - if ( defined( $defs{$device} ) && $defs{$device}{TYPE} ne "dummy" ); + if ( msgConfig_IsDevice($device) && msgConfig_GetType($device) ne "dummy" ); - if ( !defined( $defs{$device} ) ) { + if ( !msgConfig_IsDevice($device) ) { $return = fhem( "define $device dummy", 1 ); $return .= "Device $device was created" if ( $return eq "" ); @@ -361,13 +361,10 @@ sub msgConfig_Set($@) { return "Device $device is already existing but not a RESIDENTS or ROOMMATE device" - if ( - defined( $defs{$device} ) - && ( $defs{$device}{TYPE} ne "RESIDENTS" - && $defs{$device}{TYPE} ne "ROOMMATE" ) - ); + if ( msgConfig_IsDevice($device) + && !msgConfig_IsDevice( $device, "RESIDENTS|ROOMMATE" ) ); - if ( !defined( $defs{$device} ) ) { + if ( !msgConfig_IsDevice($device) ) { $return = fhem( "define $device RESIDENTS", 1 ); $return .= "RESIDENTS device $device was created." if ( $return eq "" ); @@ -375,11 +372,12 @@ sub msgConfig_Set($@) { else { $return = "Existing " - . $defs{$device}{TYPE} + . msgConfig_GetType($device) . " device $device was updated."; } - my $txt = fhem("attr $device rgr_lang $lang") unless ( $lang eq "EN" ); + my $txt = fhem("attr $device rgr_lang $lang") + unless ( $lang eq "EN" ); $return .= $txt if ($txt); $attr{$device}{comment} = "Auto-created by $name" @@ -412,7 +410,7 @@ sub msgConfig_Get($@) { Log3 $name, 5, "msgConfig $name: called function msgConfig_Get()"; - my @msgTypes = ( "audio", "light", "mail", "push", "screen", "queue" ); + my @msgTypes = ( "audio", "light", "mail", "push", "screen" ); # routeCmd if ( lc($what) eq "routecmd" ) { @@ -428,12 +426,12 @@ sub msgConfig_Get($@) { # Check device if ( $devicesReq ne "" ) { foreach my $device ( split( /,/, $devicesReq ) ) { - if ( defined( $defs{$device} ) ) { - $UserDeviceTypes .= "," . $defs{$device}{TYPE} + if ( msgConfig_IsDevice($device) ) { + $UserDeviceTypes .= "," . msgConfig_GetType($device) if ( $UserDeviceTypes ne "" && $msgType ne "mail" && $device ne $name ); - $UserDeviceTypes = $defs{$device}{TYPE} + $UserDeviceTypes = msgConfig_GetType($device) if ( $UserDeviceTypes eq "" && $msgType ne "mail" && $device ne $name ); @@ -459,53 +457,8 @@ sub msgConfig_Get($@) { my $priorityCat = ""; $priorityCat = $prio if ( $prio ne "Normal" ); - my $cmd = - - # look for direct - AttrVal( - $device, "msgCmd$typeUc$priorityCat", - - # look for indirect - AttrVal( - AttrVal( - $device, "msgRecipient$typeUc", "" - ), - "msgCmd$typeUc$priorityCat", - - #look for indirect general - AttrVal( - AttrVal( $device, "msgRecipient", "" ), - "msgCmd$typeUc$priorityCat", - - # look for global direct - AttrVal( - $name, - "msgCmd$typeUc$priorityCat", - - # look for global indirect - AttrVal( - AttrVal( - $name, - "msgRecipient$typeUc", "" - ), - "msgCmd$typeUc$priorityCat", - - #look for global indirect general - AttrVal( - AttrVal( - $name, "msgRecipient", - "" - ), - "msgCmd$typeUc$priorityCat", - - # none - "" - ) - ) - ) - ) - ) - ); + my $cmd = MSG_FindAttrVal( $device, + "msgCmd$typeUc$priorityCat", $typeUc, "" ); next if ( $cmd eq "" @@ -517,7 +470,7 @@ sub msgConfig_Get($@) { if ( $output == 0 ); $return .= " $device (DEVICE TYPE: " - . $defs{$device}{TYPE} . ")\n" + . msgConfig_GetType($device) . ")\n" if ( $output == 0 ); $output = 1 if ( $output == 0 ); @@ -627,6 +580,125 @@ sub msgConfig_Get($@) { } } +######################################## +sub MSG_FindAttrVal($$$$) { + my ( $d, $n, $msgType, $default ) = @_; + $msgType = "" unless ($msgType); + $msgType = ucfirst($msgType); + $n .= $msgType if ( $n =~ /^msg(Contact)$/ ); + + my $g = ( + ( + defined( $modules{msgConfig}{defptr} ) + && $n !~ /^(verbose|msgContact.*)$/ + ) + ? $modules{msgConfig}{defptr}{NAME} + : "" + ); + + return + + # look for direct + AttrVal( + $d, $n, + + # look for indirect + AttrVal( + AttrVal( $d, "msgRecipient$msgType", "" ), + $n, + + # look for indirect, type-independent + AttrVal( + AttrVal( $d, "msgRecipient", "" ), + $n, + + # look for global direct + AttrVal( + $g, $n, + + # look for global indirect + AttrVal( + AttrVal( $g, "msgRecipient$msgType", "" ), + $n, + + # look for global indirect, type-independent + AttrVal( + AttrVal( $g, "msgRecipient", "" ), + $n, + + # default + $default + ) + ) + ) + ) + ) + ); +} + +######################################## +sub msgConfig_FindReadingsVal($$$$) { + my ( $d, $n, $msgType, $default ) = @_; + $msgType = ucfirst($msgType) if ($msgType); + + return + + # look for direct + ReadingsVal( + $d, $n, + + # look for indirect + ReadingsVal( + AttrVal( $d, "msgRecipient$msgType", "" ), + $n, + + # look for indirect, type-independent + ReadingsVal( + AttrVal( $d, "msgRecipient", "" ), + $n, + + # default + $default + ) + ) + ); +} + +######################################## +sub msgConfig_IsDevice($;$) { + my $devname = shift; + my $devtype = shift; + $devtype = ".*" unless ( $devtype && $devtype ne "" ); + + return 1 + if ( defined($devname) + && defined( $defs{$devname} ) + && ref( $defs{$devname} ) eq "HASH" + && defined( $defs{$devname}{NAME} ) + && $defs{$devname}{NAME} eq $devname + && defined( $defs{$devname}{TYPE} ) + && $defs{$devname}{TYPE} =~ m/^$devtype$/ + && defined( $modules{ $defs{$devname}{TYPE} } ) + && defined( $modules{ $defs{$devname}{TYPE} }{LOADED} ) + && $modules{ $defs{$devname}{TYPE} }{LOADED} ); + + delete $defs{$devname} + if ( defined($devname) + && defined( $defs{$devname} ) + && $devtype eq ".*" ); + + return 0; +} + +######################################## +sub msgConfig_GetType($;$) { + my $devname = shift; + my $default = shift; + + return $default unless ( msgConfig_IsDevice($devname) ); + return $defs{$devname}{TYPE}; +} + 1; =pod