2015-09-24 12:19:46 +00:00
# $Id$
##############################################################################
#
2015-10-22 09:52:17 +00:00
# 98_message.pm
2015-09-24 12:19:46 +00:00
# Dynamic message and notification routing for FHEM
#
# Copyright by Julian Pawlowski
# e-mail: julian.pawlowski at gmail.com
#
# This file is part of fhem.
#
# Fhem is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 of the License, or
# (at your option) any later version.
#
# Fhem is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with fhem. If not, see <http://www.gnu.org/licenses/>.
#
#
# Version: 1.0.0
#
# Major Version History:
#
# - 1.0.0 - 2015-09-23
# -- First release
#
##############################################################################
package main ;
use strict ;
use warnings ;
use Time::HiRes qw( time ) ;
2015-10-12 22:18:10 +00:00
use Data::Dumper ;
2015-10-19 17:22:14 +00:00
use messageSchema ;
2015-09-24 12:19:46 +00:00
2015-10-05 08:04:23 +00:00
no if $] >= 5.017011 , warnings = > 'experimental::smartmatch' ;
2015-10-19 17:22:14 +00:00
sub CommandMessage ( $ $ ; $$ ) ;
2015-09-24 12:19:46 +00:00
########################################
2015-10-19 17:22:14 +00:00
sub message_Initialize ($$) {
2015-09-24 12:19:46 +00:00
my % hash = (
2015-10-19 17:22:14 +00:00
Fn = > "CommandMessage" ,
2015-09-24 12:19:46 +00:00
Hlp = >
2015-10-22 09:52:17 +00:00
"[<type>] [<\@device>|<e-mail address>] [<priority>] [|<title>|] <message-text>" ,
2015-09-24 12:19:46 +00:00
) ;
2015-10-19 17:22:14 +00:00
$ cmds { message } = \ % hash ;
2015-09-24 12:19:46 +00:00
}
########################################
2015-10-19 17:22:14 +00:00
sub CommandMessage ($$;$$) {
2015-09-24 12:19:46 +00:00
my ( $ cl , $ msg , $ testMode ) = @ _ ;
my $ return = "" ;
2015-10-19 17:22:14 +00:00
# find existing messageConfig device or create a new instance
2015-10-22 09:52:17 +00:00
my $ globalDevName = "messageConfig" ;
if ( defined ( $ modules { msgConfig } { defptr } ) ) {
$ globalDevName = $ modules { msgConfig } { defptr } { NAME } ;
2015-10-18 13:09:15 +00:00
} else {
2015-10-22 09:52:17 +00:00
fhem "define $globalDevName messageConfig" ;
$ return . = "Global configuration device $globalDevName was created.\n\n" ;
2015-10-18 13:09:15 +00:00
}
2015-09-24 12:19:46 +00:00
if ( $ msg eq "" || $ msg =~ /^\?[\s\t]*$/ || $ msg eq "help" ) {
return
2015-10-19 11:58:11 +00:00
$ return .
2015-10-22 09:52:17 +00:00
"Usage: message [<type>] [<\@device>|<e-mail address>] [<priority>] [|<title>|] <message>" ;
2015-09-24 12:19:46 +00:00
}
2015-10-12 22:18:10 +00:00
# default settings
2015-10-19 17:22:14 +00:00
my $ cmdSchema = messageSchema:: get ( ) ;
2015-10-12 22:18:10 +00:00
my $ settings = {
'audio' = > {
'typeEscalation' = > {
'gwUnavailable' = > 'text' ,
'emergency' = > 'text' ,
'residentGone' = > 'text' ,
'residentAbsent' = > 'text' ,
} ,
'title' = > 'Announcement' ,
} ,
'light' = > {
'typeEscalation' = > {
'gwUnavailable' = > 'audio' ,
'emergency' = > 'audio' ,
'residentGone' = > 'audio' ,
'residentAbsent' = > 'audio' ,
} ,
'title' = > 'Announcement' ,
} ,
'mail' = > {
'title' = > 'System Message' ,
} ,
'push' = > {
'typeEscalation' = > {
'gwUnavailable' = > 'mail' ,
'emergency' = > 'mail' ,
} ,
'title' = > 'System Message' ,
} ,
'screen' = > {
'typeEscalation' = > {
'gwUnavailable' = > 'light' ,
'emergency' = > 'light' ,
'residentGone' = > 'light' ,
'residentAbsent' = > 'light' ,
} ,
'title' = > 'Info' ,
} ,
} ;
2015-09-24 12:19:46 +00:00
################################################################
### extract message details
###
my $ types = "" ;
my $ recipients = "" ;
my $ priority = "" ;
2015-10-12 22:18:10 +00:00
my $ title = "-" ;
my $ advanced = "" ;
2015-09-24 12:19:46 +00:00
my $ priorityCat = "" ;
# check for message types
if ( $ msg =~
s/^[\s\t]*([a-z,]*!?(screen|light|audio|text|push|mail)[a-z,!|]*)[\s\t]+//
)
{
$ types = $ 1 ;
}
# check for given recipients
if ( $ msg =~
s/^[\s\t]*([!]?(([A-Za-z0-9%+._-])*@([%+a-z0-9A-Z.-]+))[\w,@.!|]*)[\s\t]+//
)
{
$ recipients = $ 1 ;
}
# check for given priority
if ( $ msg =~ s/^[\s\t]*([-+]{0,1}\d+[.\d]*)[\s\t]*// ) {
$ priority = $ 1 ;
}
# check for given message title
if ( $ msg =~
s/^[\s\t]*\|([\w\süöäß^°!"§$%&\/\\()<>=?´ `"+\[\]#*@€]+)\|[\s\t]+//
)
{
$ title = $ 1 ;
}
2015-10-12 22:18:10 +00:00
# check for advanced options
if ( $ msg =~ s/[\s\t]*O(\[\{.*\}\])[\s\t]*$// )
{
# Use JSON module if possible
eval 'use JSON qw( decode_json ); 1' ;
if ( ! $@ ) {
$ advanced = decode_json ( Encode:: encode_utf8 ( $ 1 ) ) ;
2015-10-22 09:52:17 +00:00
Log3 $ globalDevName , 5 , "message: Advanced options\n" . Dumper ( $ advanced ) ;
2015-10-12 22:18:10 +00:00
} else {
2015-10-22 09:52:17 +00:00
Log3 $ globalDevName , 3 , "message: To use advanced options, please install Perl::JSON." ;
2015-10-12 22:18:10 +00:00
}
}
2015-09-24 12:19:46 +00:00
################################################################
### command queue
###
$ types = "text"
if ( $ types eq "" ) ;
my $ messageSent = 0 ;
my $ forwarded = "" ;
my % sentTypesPerDevice ;
my $ sentCounter = 0 ;
my $ messageID = time ( ) ;
my $ isTypeOr = 1 ;
my $ isRecipientOr = 1 ;
my $ hasTypeOr = 0 ;
my $ hasRecipientOr = 0 ;
2015-10-18 13:09:15 +00:00
$ recipients = "\@" . $ globalDevName if ( $ recipients eq "" ) ;
2015-09-24 12:19:46 +00:00
my @ typesOr = split ( /\|/ , $ types ) ;
$ hasTypeOr = 1 if ( scalar ( grep { defined $ _ } @ typesOr ) > 1 ) ;
2015-10-18 13:09:15 +00:00
Log3 $ globalDevName , 5 ,
2015-10-22 09:52:17 +00:00
"message: typeOr total is " . scalar ( grep { defined $ _ } @ typesOr )
2015-09-24 12:19:46 +00:00
if ( $ testMode ne "1" ) ;
for (
my $ iTypesOr = 0 ;
$ iTypesOr < scalar ( grep { defined $ _ } @ typesOr ) ;
$ iTypesOr + +
)
{
2015-10-18 13:09:15 +00:00
Log3 $ globalDevName , 5 ,
2015-10-22 09:52:17 +00:00
"message: start typeOr loop for type(s) $typesOr[$iTypesOr]"
2015-09-24 12:19:46 +00:00
if ( $ testMode ne "1" ) ;
my @ type = split ( /,/ , $ typesOr [ $ iTypesOr ] ) ;
for ( my $ i = 0 ; $ i < scalar ( grep { defined $ _ } @ type ) ; $ i + + ) {
2015-10-22 09:52:17 +00:00
Log3 $ globalDevName , 5 , "message: running loop for type $type[$i]"
2015-09-24 12:19:46 +00:00
if ( $ testMode ne "1" ) ;
last if ( ! defined ( $ type [ $ i ] ) ) ;
my $ forceType = 0 ;
2015-10-15 10:52:17 +00:00
if ( $ type [ $ i ] =~ s/(.*)![\s\t]*$// ) {
2015-09-24 12:19:46 +00:00
$ type [ $ i ] = $ 1 ;
$ forceType = 1 ;
}
# check for correct type
my @ msgCmds =
( "screen" , "light" , "audio" , "text" , "push" , "mail" ) ;
if ( ! ( $ type [ $ i ] ~ ~ @ msgCmds ) ) {
$ return . = "Unknown message type $type[$i]\n" ;
next ;
}
################################################################
### recipient loop
###
my @ recipientsOr = split ( /\|/ , $ recipients ) ;
$ hasRecipientOr = 1
if ( scalar ( grep { defined $ _ } @ recipientsOr ) > 1 ) ;
2015-10-18 13:09:15 +00:00
Log3 $ globalDevName , 5 ,
2015-10-22 09:52:17 +00:00
"message: recipientOr total is "
2015-09-24 12:19:46 +00:00
. scalar ( grep { defined $ _ } @ recipientsOr )
if ( $ testMode ne "1" ) ;
for (
my $ iRecipOr = 0 ;
$ iRecipOr < scalar ( grep { defined $ _ } @ recipientsOr ) ;
$ iRecipOr + +
)
{
2015-10-18 13:09:15 +00:00
Log3 $ globalDevName , 5 ,
2015-10-22 09:52:17 +00:00
"message: start recipientsOr loop for recipient(s) $recipientsOr[$iRecipOr]"
2015-09-24 12:19:46 +00:00
if ( $ testMode ne "1" ) ;
my @ recipient = split ( /,/ , $ recipientsOr [ $ iRecipOr ] ) ;
foreach my $ device ( @ recipient ) {
2015-10-22 09:52:17 +00:00
Log3 $ globalDevName , 5 , "message: running loop for device $device"
2015-09-24 12:19:46 +00:00
if ( $ testMode ne "1" ) ;
my $ messageSentDev = 0 ;
my $ gatewayDevs = "" ;
my $ forceDevice = 0 ;
# for device type
my $ deviceType = "device" ;
if ( $ device =~
/^(([A-Za-z0-9%+._-])+[@]+([%+a-z0-9A-Z.-]*))$/ )
{
$ gatewayDevs = $ 1 ;
$ deviceType = "email" ;
}
2015-10-15 10:52:17 +00:00
elsif ( $ device =~ s/^@?(.*)![\s\t]*$// ) {
2015-09-24 12:19:46 +00:00
$ device = $ 1 ;
$ forceDevice = 1 ;
}
elsif ( $ device =~ s/^@(.*)// ) {
$ device = $ 1 ;
}
# FATAL ERROR: device does not exist
if ( ! defined ( $ defs { $ device } )
&& $ deviceType eq "device" )
{
$ return . = "Device $device does not exist\n" ;
2015-10-22 09:52:17 +00:00
Log3 $ globalDevName , 5 , "message $device: Device does not exist"
2015-09-24 12:19:46 +00:00
if ( $ testMode ne "1" ) ;
my $ regex1 =
2015-10-12 22:18:10 +00:00
"\\s*!?@?" . $ device . "[,|]" ; # at the beginning
my $ regex2 = "[,|]!?@?" . $ device . "\\s*" ; # at the end
2015-09-24 12:19:46 +00:00
my $ regex3 =
",!?@?" . $ device . "," ; # in the middle with comma
my $ regex4 =
"[\|,]!?@?"
. $ device
. "[\|,]" ; # in the middle with pipe and/or comma
2015-10-12 22:18:10 +00:00
$ recipients =~ s/^$regex1//gi ;
$ recipients =~ s/$regex2$/|/gi ;
$ recipients =~ s/$regex3/,/gi ;
$ recipients =~ s/$regex4/|/gi ;
2015-09-24 12:19:46 +00:00
next ;
}
my $ typeUc = ucfirst ( $ type [ $ i ] ) ;
my $ catchall = 0 ;
my $ useLocation = 0 ;
my $ logDevice ;
2015-10-18 13:09:15 +00:00
$ logDevice = $ globalDevName ;
2015-09-24 12:19:46 +00:00
$ logDevice = $ device
if (
# look for direct
AttrVal (
$ device , "verbose" ,
#look for indirect
AttrVal (
AttrVal ( $ device , "msgRecipient$typeUc" , "" ) ,
"verbose" ,
#look for indirect general
AttrVal (
AttrVal ( $ device , "msgRecipient" , "" ) ,
"verbose" ,
# no verbose found
""
)
)
) ne ""
) ;
################################################################
### get target information from device location
###
# search for location references
my @ locationDevs ;
@ locationDevs = split (
/,/ ,
# look for direct
AttrVal (
$ device , "msgLocationDevs" ,
#look for indirect
AttrVal (
AttrVal ( $ device , "msgRecipient$typeUc" , "" ) ,
"msgLocationDevs" ,
# look for indirect general
AttrVal (
AttrVal ( $ device , "msgRecipient" , "" ) ,
"msgLocationDevs" ,
# look for global direct
AttrVal (
2015-10-18 13:09:15 +00:00
$ globalDevName , "msgLocationDevs" ,
2015-09-24 12:19:46 +00:00
#look for global indirect
AttrVal (
AttrVal (
2015-10-18 13:09:15 +00:00
$ globalDevName ,
2015-09-24 12:19:46 +00:00
"msgRecipient$typeUc" , ""
) ,
"msgLocationDevs" ,
# look for global indirect general
AttrVal (
AttrVal (
2015-10-18 13:09:15 +00:00
$ globalDevName , "msgRecipient" ,
2015-09-24 12:19:46 +00:00
""
) ,
"msgLocationDevs" ,
# no locations defined
""
)
)
)
)
)
)
) ;
if ( $ deviceType eq "device" ) {
# get device location
my $ deviceLocation =
# look for direct
ReadingsVal (
$ device , "location" ,
# look for indirect
ReadingsVal (
AttrVal ( $ device , "msgRecipient$typeUc" , "" ) ,
"location" ,
# look for indirect general
ReadingsVal (
AttrVal ( $ device , "msgRecipient" , "" ) ,
"location" ,
# no location found
""
)
)
) ;
my $ locationDev = "" ;
if ( $ deviceLocation ne "" ) {
# lookup matching location
foreach ( @ locationDevs ) {
my $ lName =
AttrVal ( $ _ , "msgLocationName" , "" ) ;
if ( $ lName ne "" && $ lName eq $ deviceLocation )
{
$ locationDev = $ _ ;
last ;
}
}
# look for gateway device
$ gatewayDevs =
# look for direct
AttrVal (
$ locationDev , "msgContact$typeUc" ,
# look for indirect
AttrVal (
AttrVal (
$ locationDev , "msgRecipient$typeUc" ,
""
) ,
"msgContact$typeUc" ,
# look for indirect general
AttrVal (
AttrVal (
$ locationDev , "msgRecipient" ,
""
) ,
"msgContact$typeUc" ,
# no contact found
""
)
)
) ;
# at least one of the location gateways needs to
# be available. Otherwise we fall back to
# non-location contacts
if ( $ gatewayDevs ne "" ) {
foreach
my $ gatewayDevOr ( split /\|/ , $ gatewayDevs )
{
foreach my $ gatewayDev ( split /,/ ,
$ gatewayDevOr )
{
2015-10-18 16:33:00 +00:00
my $ subRecipient = "" ;
if ( $ gatewayDev =~ s/:(.*)// )
{
$ subRecipient = $ 1 ;
}
2015-09-24 12:19:46 +00:00
if ( $ type [ $ i ] ne "mail"
&& ! defined ( $ defs { $ gatewayDev } )
&& $ deviceType eq "device" )
{
$ useLocation = 2
if ( $ useLocation == 0 ) ;
}
elsif (
$ type [ $ i ] ne "mail"
&& AttrVal ( $ gatewayDev , "disable" ,
"0" ) eq "1"
)
{
$ useLocation = 2
if ( $ useLocation == 0 ) ;
}
elsif (
$ type [ $ i ] ne "mail"
&& (
AttrVal (
$ gatewayDev , "disable" ,
"0"
) eq "1"
|| ReadingsVal (
$ gatewayDev , "power" ,
"on"
) eq "off"
|| ReadingsVal (
$ gatewayDev , "presence" ,
"present"
) eq "absent"
|| ReadingsVal (
$ gatewayDev , "presence" ,
"appeared"
) eq "disappeared"
|| ReadingsVal (
$ gatewayDev , "state" ,
"present"
) eq "absent"
|| ReadingsVal (
$ gatewayDev , "state" ,
"connected"
) eq "unauthorized"
|| ReadingsVal (
$ gatewayDev , "state" ,
"connected"
) eq "disconnected"
|| ReadingsVal (
$ gatewayDev , "state" ,
"reachable"
) eq "unreachable"
|| ReadingsVal (
$ gatewayDev , "available" ,
"1"
) eq "0"
|| ReadingsVal (
$ gatewayDev , "available" ,
"yes"
) eq "no"
|| ReadingsVal (
$ gatewayDev , "reachable" ,
"1"
) eq "0"
|| ReadingsVal (
$ gatewayDev , "reachable" ,
"yes"
) eq "no"
)
)
{
$ useLocation = 2
if ( $ useLocation == 0 ) ;
}
else {
$ useLocation = 1 ;
}
}
}
# use gatewayDevs from location only
# if it has been confirmed to be available
if ( $ useLocation == 1 ) {
Log3 $ logDevice , 4 ,
2015-10-22 09:52:17 +00:00
"message $device: Matching location definition found." ;
2015-09-24 12:19:46 +00:00
}
else {
$ gatewayDevs = "" ;
}
}
}
}
################################################################
### given device name is already a gateway device itself
###
2015-10-12 22:18:10 +00:00
my $ deviceType2 = defined ( $ defs { $ device } ) ? $ defs { $ device } { TYPE } : "" ;
2015-09-24 12:19:46 +00:00
if (
$ gatewayDevs eq ""
2015-10-12 22:18:10 +00:00
&& $ deviceType2 ne ""
2015-09-24 12:19:46 +00:00
&& (
2015-10-12 22:18:10 +00:00
( $ type [ $ i ] eq "audio" && defined ( $ cmdSchema - > { $ type [ $ i ] } { $ deviceType2 } ) ) ||
( $ type [ $ i ] eq "light" && defined ( $ cmdSchema - > { $ type [ $ i ] } { $ deviceType2 } ) ) ||
( $ type [ $ i ] eq "push" && defined ( $ cmdSchema - > { $ type [ $ i ] } { $ deviceType2 } ) ) ||
( $ type [ $ i ] eq "screen" && defined ( $ cmdSchema - > { $ type [ $ i ] } { $ deviceType2 } ) )
2015-09-24 12:19:46 +00:00
)
)
{
Log3 $ logDevice , 4 ,
2015-10-22 09:52:17 +00:00
"message $device: This recipient seems to be a gateway device itself. Still checking for any delegates ..." ;
2015-09-24 12:19:46 +00:00
$ gatewayDevs =
# look for direct
AttrVal (
$ device ,
"msgContact$typeUc" ,
# look for indirect
AttrVal (
AttrVal ( $ device , "msgRecipient$typeUc" , "" ) ,
"msgContact$typeUc" ,
# look for indirect general
AttrVal (
AttrVal ( $ device , "msgRecipient" , "" ) ,
"msgContact$typeUc" ,
# self
$ device
)
)
) ;
}
################################################################
### get target information from device
###
elsif ( $ deviceType eq "device" && $ gatewayDevs eq "" ) {
# look for gateway device
$ gatewayDevs =
# look for direct
AttrVal (
$ device , "msgContact$typeUc" ,
#look for indirect
AttrVal (
AttrVal ( $ device , "msgRecipient$typeUc" , "" ) ,
"msgContact$typeUc" ,
#look for indirect general
AttrVal (
AttrVal ( $ device , "msgRecipient" , "" ) ,
"msgContact$typeUc" ,
# no contact found
""
)
)
) ;
# fallback/catchall
if ( $ gatewayDevs eq "" ) {
$ catchall = 1
2015-10-18 13:09:15 +00:00
if ( $ device ne $ globalDevName ) ;
2015-09-24 12:19:46 +00:00
Log3 $ logDevice , 5 ,
2015-10-22 09:52:17 +00:00
"message $device: (No $typeUc contact defined, trying global instead)"
2015-09-24 12:19:46 +00:00
if ( $ catchall == 1 ) ;
$ gatewayDevs =
# look for direct
AttrVal (
2015-10-18 13:09:15 +00:00
$ globalDevName , "msgContact$typeUc" ,
2015-09-24 12:19:46 +00:00
#look for indirect
AttrVal (
AttrVal (
2015-10-18 13:09:15 +00:00
$ globalDevName , "msgRecipient$typeUc" , ""
2015-09-24 12:19:46 +00:00
) ,
"msgContact$typeUc" ,
#look for indirect general
AttrVal (
2015-10-18 13:09:15 +00:00
AttrVal ( $ globalDevName , "msgRecipient" , "" ) ,
2015-09-24 12:19:46 +00:00
"msgContact$typeUc" ,
# no contact found
""
)
)
) ;
}
}
# Find priority if none was explicitly specified
my $ loopPriority = $ priority ;
$ loopPriority =
# look for direct
AttrVal (
$ device , "msgPriority$typeUc" ,
#look for indirect
AttrVal (
AttrVal ( $ device , "msgRecipient$typeUc" , "" ) ,
"msgPriority$typeUc" ,
#look for indirect general
AttrVal (
AttrVal ( $ device , "msgRecipient" , "" ) ,
"msgPriority$typeUc" ,
# look for global direct
AttrVal (
2015-10-18 13:09:15 +00:00
$ globalDevName , "msgPriority$typeUc" ,
2015-09-24 12:19:46 +00:00
#look for global indirect
AttrVal (
AttrVal (
2015-10-18 13:09:15 +00:00
$ globalDevName , "msgRecipient$typeUc" ,
2015-09-24 12:19:46 +00:00
""
) ,
"msgPriority$typeUc" ,
#look for global indirect general
AttrVal (
AttrVal (
2015-10-18 13:09:15 +00:00
$ globalDevName , "msgRecipient" ,
2015-09-24 12:19:46 +00:00
""
) ,
"msgPriority$typeUc" ,
# default
0
)
)
)
)
)
) if ( ! $ priority ) ;
# check for available routes
#
my % routes ;
$ routes { screen } = 0 ;
$ routes { light } = 0 ;
$ routes { audio } = 0 ;
$ routes { text } = 0 ;
$ routes { push } = 0 ;
$ routes { mail } = 0 ;
if (
! defined ( $ testMode )
|| ( $ testMode ne "1"
&& $ testMode ne "2" )
)
{
Log3 $ logDevice , 5 ,
2015-10-22 09:52:17 +00:00
"message $device: Checking for available routes (triggered by type $type[$i])" ;
2015-09-24 12:19:46 +00:00
$ routes { screen } = 1
if (
$ deviceType eq "device"
2015-10-19 17:22:14 +00:00
&& CommandMessage ( "screen" ,
2015-09-24 12:19:46 +00:00
"screen \@$device $priority Routing Test" , 1 )
eq "ROUTE_AVAILABLE"
) ;
$ routes { light } = 1
if (
$ deviceType eq "device"
2015-10-19 17:22:14 +00:00
&& CommandMessage ( "light" ,
2015-09-24 12:19:46 +00:00
"light \@$device $priority Routing Test" , 1 )
eq "ROUTE_AVAILABLE"
) ;
$ routes { audio } = 1
if (
$ deviceType eq "device"
2015-10-19 17:22:14 +00:00
&& CommandMessage ( "audio" ,
2015-09-24 12:19:46 +00:00
"audio \@$device $priority Routing Test" , 1 )
eq "ROUTE_AVAILABLE"
) ;
if (
$ deviceType eq "device"
2015-10-19 17:22:14 +00:00
&& CommandMessage ( "push" ,
2015-09-24 12:19:46 +00:00
"push \@$device $priority Routing Test" , 1 ) eq
"ROUTE_AVAILABLE"
)
{
$ routes { push } = 1 ;
$ routes { text } = 1 ;
}
if (
2015-10-19 17:22:14 +00:00
CommandMessage ( "mail" ,
2015-09-24 12:19:46 +00:00
"mail \@$device $priority Routing Test" , 1 ) eq
"ROUTE_AVAILABLE"
)
{
$ routes { mail } = 1 ;
$ routes { text } = 1 ;
}
Log3 $ logDevice , 4 ,
2015-10-22 09:52:17 +00:00
"message $device: Available routes: screen="
2015-09-24 12:19:46 +00:00
. $ routes { screen }
. " light="
. $ routes { light }
. " audio="
. $ routes { audio }
. " text="
. $ routes { text }
. " push="
. $ routes { push }
. " mail="
. $ routes { mail } ;
}
##################################################
### dynamic routing for text (->push, ->mail)
###
if ( $ type [ $ i ] eq "text" ) {
2015-10-06 09:10:01 +00:00
# user selected emergency priority text threshold
my $ prioThresTextEmg =
# look for direct
AttrVal (
$ device , "msgThPrioTextEmergency" ,
#look for indirect audio
AttrVal (
AttrVal ( $ device , "msgRecipient$typeUc" , "" ) ,
"msgThPrioTextEmergency" ,
#look for indirect general
AttrVal (
AttrVal ( $ device , "msgRecipient" , "" ) ,
"msgThPrioTextEmergency" ,
# look for global direct
AttrVal (
2015-10-18 13:09:15 +00:00
$ globalDevName , "msgThPrioTextEmergency" ,
2015-10-06 09:10:01 +00:00
#look for global indirect type
AttrVal (
AttrVal (
2015-10-18 13:09:15 +00:00
$ globalDevName ,
2015-10-06 09:10:01 +00:00
"msgRecipient$typeUc" , ""
) ,
"msgThPrioTextEmergency" ,
#look for global indirect general
AttrVal (
AttrVal (
2015-10-18 13:09:15 +00:00
$ globalDevName , "msgRecipient" ,
2015-10-06 09:10:01 +00:00
""
) ,
"msgThPrioTextEmergency" ,
# default
"2"
)
)
)
)
)
)
;
# user selected low priority text threshold
my $ prioThresTextNormal =
# look for direct
AttrVal (
$ device , "msgThPrioTextNormal" ,
#look for indirect audio
AttrVal (
AttrVal ( $ device , "msgRecipient$typeUc" , "" ) ,
"msgThPrioTextNormal" ,
#look for indirect general
AttrVal (
AttrVal ( $ device , "msgRecipient" , "" ) ,
"msgThPrioTextNormal" ,
# look for global direct
AttrVal (
2015-10-18 13:09:15 +00:00
$ globalDevName , "msgThPrioTextNormal" ,
2015-10-06 09:10:01 +00:00
#look for global indirect type
AttrVal (
AttrVal (
2015-10-18 13:09:15 +00:00
$ globalDevName ,
2015-10-06 09:10:01 +00:00
"msgRecipient$typeUc" , ""
) ,
"msgThPrioTextNormal" ,
#look for global indirect general
AttrVal (
AttrVal (
2015-10-18 13:09:15 +00:00
$ globalDevName , "msgRecipient" ,
2015-10-06 09:10:01 +00:00
""
) ,
"msgThPrioTextNormal" ,
# default
"-2"
)
)
)
)
)
)
;
2015-09-24 12:19:46 +00:00
# Decide push and/or e-mail destination based on priorities
2015-10-06 09:10:01 +00:00
if ( $ loopPriority >= $ prioThresTextEmg
2015-09-24 12:19:46 +00:00
&& $ routes { push } == 1
&& $ routes { mail } == 1 )
{
Log3 $ logDevice , 4 ,
2015-10-22 09:52:17 +00:00
"message $device: Text routing decision: push+mail(1)" ;
2015-09-24 12:19:46 +00:00
$ forwarded . = ","
if ( $ forwarded ne "" ) ;
$ forwarded . = "text>push+mail" ;
push @ type , "push" if ! ( "push" ~ ~ @ type ) ;
push @ type , "mail" if ! ( "mail" ~ ~ @ type ) ;
}
2015-10-06 09:10:01 +00:00
elsif ( $ loopPriority >= $ prioThresTextEmg
2015-09-24 12:19:46 +00:00
&& $ routes { push } == 1
&& $ routes { mail } == 0 )
{
Log3 $ logDevice , 4 ,
2015-10-22 09:52:17 +00:00
"message $device: Text routing decision: push(2)" ;
2015-09-24 12:19:46 +00:00
$ forwarded . = ","
if ( $ forwarded ne "" ) ;
$ forwarded . = "text>push" ;
push @ type , "push" if ! ( "push" ~ ~ @ type ) ;
}
2015-10-06 09:10:01 +00:00
elsif ( $ loopPriority >= $ prioThresTextEmg
2015-09-24 12:19:46 +00:00
&& $ routes { push } == 0
&& $ routes { mail } == 1 )
{
Log3 $ logDevice , 4 ,
2015-10-22 09:52:17 +00:00
"message $device: Text routing decision: mail(3)" ;
2015-09-24 12:19:46 +00:00
$ forwarded . = ","
if ( $ forwarded ne "" ) ;
$ forwarded . = "text>mail" ;
push @ type , "mail" if ! ( "mail" ~ ~ @ type ) ;
}
2015-10-06 09:10:01 +00:00
elsif ( $ loopPriority >= $ prioThresTextNormal && $ routes { push } == 1 ) {
2015-09-24 12:19:46 +00:00
Log3 $ logDevice , 4 ,
2015-10-22 09:52:17 +00:00
"message $device: Text routing decision: push(4)" ;
2015-09-24 12:19:46 +00:00
$ forwarded . = ","
if ( $ forwarded ne "" ) ;
$ forwarded . = "text>push" ;
push @ type , "push" if ! ( "push" ~ ~ @ type ) ;
}
2015-10-06 09:10:01 +00:00
elsif ( $ loopPriority >= $ prioThresTextNormal && $ routes { mail } == 1 ) {
2015-09-24 12:19:46 +00:00
Log3 $ logDevice , 4 ,
2015-10-22 09:52:17 +00:00
"message $device: Text routing decision: mail(5)" ;
2015-09-24 12:19:46 +00:00
$ forwarded . = ","
if ( $ forwarded ne "" ) ;
$ forwarded . = "text>mail" ;
push @ type , "mail" if ! ( "mail" ~ ~ @ type ) ;
}
elsif ( $ routes { mail } == 1 ) {
Log3 $ logDevice , 4 ,
2015-10-22 09:52:17 +00:00
"message $device: Text routing decision: mail(6)" ;
2015-09-24 12:19:46 +00:00
$ forwarded . = ","
if ( $ forwarded ne "" ) ;
$ forwarded . = "text>mail" ;
push @ type , "mail" if ! ( "mail" ~ ~ @ type ) ;
}
elsif ( $ routes { push } == 1 ) {
Log3 $ logDevice , 4 ,
2015-10-22 09:52:17 +00:00
"message $device: Text routing decision: push(7)" ;
2015-09-24 12:19:46 +00:00
$ forwarded . = ","
if ( $ forwarded ne "" ) ;
$ forwarded . = "text>push" ;
push @ type , "push" if ! ( "push" ~ ~ @ type ) ;
}
# FATAL ERROR: routing decision failed
else {
Log3 $ logDevice , 4 ,
2015-10-22 09:52:17 +00:00
"message $device: Text routing FAILED - priority=$loopPriority push="
2015-09-24 12:19:46 +00:00
. $ routes { push }
. " mail="
. $ routes { mail } ;
$ return . =
"ERROR: Could not find any Push or Mail contact for device $device - set attributes: msgContactPush | msgContactMail | msgContactText | msgRecipientPush | msgRecipientMail | msgRecipientText | msgRecipient\n" ;
}
next ;
}
# FATAL ERROR: we could not find any targets for
# user specified device...
if ( $ gatewayDevs eq ""
2015-10-18 13:09:15 +00:00
&& $ device ne $ globalDevName )
2015-09-24 12:19:46 +00:00
{
$ return . =
"ERROR: Could not find any $typeUc contact for device $device - set attributes: msgContact$typeUc | msgRecipient$typeUc | msgRecipient\n" ;
}
# FATAL ERROR: we could not find any targets at all
elsif ( $ gatewayDevs eq "" ) {
$ return . =
"ERROR: No global $typeUc contact defined. Please specify a destination device or set global attributes: msgContact$typeUc | msgRecipient$typeUc | msgRecipient\n" ;
}
#####################
# return if we are in routing target test mode
#
if ( defined ( $ testMode ) && $ testMode eq "1" ) {
Log3 $ logDevice , 5 ,
2015-10-22 09:52:17 +00:00
"message $device: $type[$i] route check result: ROUTE_AVAILABLE"
2015-09-24 12:19:46 +00:00
if ( $ return eq "" ) ;
Log3 $ logDevice , 5 ,
2015-10-22 09:52:17 +00:00
"message $device: $type[$i] route check result: ROUTE_UNAVAILABLE"
2015-09-24 12:19:46 +00:00
if ( $ return ne "" ) ;
return "ROUTE_AVAILABLE" if ( $ return eq "" ) ;
return "ROUTE_UNAVAILABLE" if ( $ return ne "" ) ;
}
2015-10-06 09:10:01 +00:00
# user selected audio-visual announcement state
2015-09-24 12:19:46 +00:00
my $ annState = ReadingsVal (
# look for direct
AttrVal (
$ device , "msgSwitcherDev" ,
#look for indirect audio
AttrVal (
AttrVal ( $ device , "msgRecipient$typeUc" , "" ) ,
"msgSwitcherDev" ,
#look for indirect general
AttrVal (
AttrVal ( $ device , "msgRecipient" , "" ) ,
"msgSwitcherDev" ,
# look for global direct
AttrVal (
2015-10-18 13:09:15 +00:00
$ globalDevName , "msgSwitcherDev" ,
2015-09-24 12:19:46 +00:00
2015-10-06 09:10:01 +00:00
#look for global indirect type
2015-09-24 12:19:46 +00:00
AttrVal (
AttrVal (
2015-10-18 13:09:15 +00:00
$ globalDevName ,
2015-09-24 12:19:46 +00:00
"msgRecipient$typeUc" , ""
) ,
"msgSwitcherDev" ,
#look for global indirect general
AttrVal (
AttrVal (
2015-10-18 13:09:15 +00:00
$ globalDevName , "msgRecipient" ,
2015-09-24 12:19:46 +00:00
""
) ,
"msgSwitcherDev" ,
# default
""
)
)
)
)
)
) ,
"state" ,
"long"
) ;
2015-10-06 09:10:01 +00:00
# user selected emergency priority audio threshold
my $ prioThresAudioEmg =
# look for direct
AttrVal (
$ device , "msgThPrioAudioEmergency" ,
#look for indirect audio
AttrVal (
AttrVal ( $ device , "msgRecipient$typeUc" , "" ) ,
"msgThPrioAudioEmergency" ,
#look for indirect general
AttrVal (
AttrVal ( $ device , "msgRecipient" , "" ) ,
"msgThPrioAudioEmergency" ,
# look for global direct
AttrVal (
2015-10-18 13:09:15 +00:00
$ globalDevName , "msgThPrioAudioEmergency" ,
2015-10-06 09:10:01 +00:00
#look for global indirect type
AttrVal (
AttrVal (
2015-10-18 13:09:15 +00:00
$ globalDevName ,
2015-10-06 09:10:01 +00:00
"msgRecipient$typeUc" , ""
) ,
"msgThPrioAudioEmergency" ,
#look for global indirect general
AttrVal (
AttrVal (
2015-10-18 13:09:15 +00:00
$ globalDevName , "msgRecipient" ,
2015-10-06 09:10:01 +00:00
""
) ,
"msgThPrioAudioEmergency" ,
# default
"2"
)
)
)
)
)
)
;
# user selected high priority audio threshold
my $ prioThresAudioHigh =
# look for direct
AttrVal (
$ device , "msgThPrioAudioHigh" ,
#look for indirect audio
AttrVal (
AttrVal ( $ device , "msgRecipient$typeUc" , "" ) ,
"msgThPrioAudioHigh" ,
#look for indirect general
AttrVal (
AttrVal ( $ device , "msgRecipient" , "" ) ,
"msgThPrioAudioHigh" ,
# look for global direct
AttrVal (
2015-10-18 13:09:15 +00:00
$ globalDevName , "msgThPrioAudioHigh" ,
2015-10-06 09:10:01 +00:00
#look for global indirect type
AttrVal (
AttrVal (
2015-10-18 13:09:15 +00:00
$ globalDevName ,
2015-10-06 09:10:01 +00:00
"msgRecipient$typeUc" , ""
) ,
"msgThPrioAudioHigh" ,
#look for global indirect general
AttrVal (
AttrVal (
2015-10-18 13:09:15 +00:00
$ globalDevName , "msgRecipient" ,
2015-10-06 09:10:01 +00:00
""
) ,
"msgThPrioAudioHigh" ,
# default
"1"
)
)
)
)
)
)
;
# user selected high priority threshold
my $ prioThresHigh =
# look for direct
AttrVal (
$ device , "msgThPrioHigh" ,
#look for indirect audio
AttrVal (
AttrVal ( $ device , "msgRecipient$typeUc" , "" ) ,
"msgThPrioHigh" ,
#look for indirect general
AttrVal (
AttrVal ( $ device , "msgRecipient" , "" ) ,
"msgThPrioHigh" ,
# look for global direct
AttrVal (
2015-10-18 13:09:15 +00:00
$ globalDevName , "msgThPrioHigh" ,
2015-10-06 09:10:01 +00:00
#look for global indirect type
AttrVal (
AttrVal (
2015-10-18 13:09:15 +00:00
$ globalDevName ,
2015-10-06 09:10:01 +00:00
"msgRecipient$typeUc" , ""
) ,
"msgThPrioHigh" ,
#look for global indirect general
AttrVal (
AttrVal (
2015-10-18 13:09:15 +00:00
$ globalDevName , "msgRecipient" ,
2015-10-06 09:10:01 +00:00
""
) ,
"msgThPrioHigh" ,
# default
"2"
)
)
)
)
)
)
;
# user selected normal priority threshold
my $ prioThresNormal =
# look for direct
AttrVal (
$ device , "msgThPrioNormal" ,
#look for indirect audio
AttrVal (
AttrVal ( $ device , "msgRecipient$typeUc" , "" ) ,
"msgThPrioNormal" ,
#look for indirect general
AttrVal (
AttrVal ( $ device , "msgRecipient" , "" ) ,
"msgThPrioNormal" ,
# look for global direct
AttrVal (
2015-10-18 13:09:15 +00:00
$ globalDevName , "msgThPrioNormal" ,
2015-10-06 09:10:01 +00:00
#look for global indirect type
AttrVal (
AttrVal (
2015-10-18 13:09:15 +00:00
$ globalDevName ,
2015-10-06 09:10:01 +00:00
"msgRecipient$typeUc" , ""
) ,
"msgThPrioNormal" ,
#look for global indirect general
AttrVal (
AttrVal (
2015-10-18 13:09:15 +00:00
$ globalDevName , "msgRecipient" ,
2015-10-06 09:10:01 +00:00
""
) ,
"msgThPrioNormal" ,
# default
"0"
)
)
)
)
)
)
;
2015-09-24 12:19:46 +00:00
if ( $ type [ $ i ] eq "audio" ) {
if ( $ annState eq "long"
|| $ forceType == 1
|| $ forceDevice == 1
2015-10-06 09:10:01 +00:00
|| $ loopPriority >= $ prioThresAudioEmg )
2015-09-24 12:19:46 +00:00
{
$ priorityCat = "" ;
}
2015-10-06 09:10:01 +00:00
elsif ( $ loopPriority >= $ prioThresAudioHigh ) {
2015-09-24 12:19:46 +00:00
$ priorityCat = "ShortPrio" ;
}
else {
$ priorityCat = "Short" ;
}
}
else {
2015-10-06 09:10:01 +00:00
if ( $ loopPriority >= $ prioThresHigh ) {
2015-09-24 12:19:46 +00:00
$ priorityCat = "High" ;
}
2015-10-06 09:10:01 +00:00
elsif ( $ loopPriority >= $ prioThresNormal ) {
2015-09-24 12:19:46 +00:00
$ priorityCat = "" ;
}
else {
$ priorityCat = "Low" ;
}
}
# get resident presence information
#
my $ residentDevState = "" ;
my $ residentDevPresence = "" ;
# device
if ( ReadingsVal ( $ device , "presence" , "-" ) ne "-" ) {
$ residentDevState = ReadingsVal ( $ device , "state" , "" ) ;
$ residentDevPresence =
ReadingsVal ( $ device , "presence" , "" ) ;
}
# device indirect
if (
(
$ residentDevState eq ""
|| $ residentDevPresence eq ""
)
&& ReadingsVal (
AttrVal ( $ device , "msgRecipient$typeUc" , "" ) ,
"presence" , "-" ) ne "-"
)
{
$ residentDevState =
ReadingsVal (
AttrVal ( $ device , "msgRecipient$typeUc" , "" ) ,
"state" , "" )
if ( $ residentDevState eq "" ) ;
$ residentDevPresence =
ReadingsVal (
AttrVal ( $ device , "msgRecipient$typeUc" , "" ) ,
"presence" , "" )
if ( $ residentDevPresence eq "" ) ;
}
# device indirect general
if (
(
$ residentDevState eq ""
|| $ residentDevPresence eq ""
)
&& ReadingsVal ( AttrVal ( $ device , "msgRecipient" , "" ) ,
"presence" , "-" ) ne "-"
)
{
$ residentDevState =
ReadingsVal ( AttrVal ( $ device , "msgRecipient" , "" ) ,
"state" , "" )
if ( $ residentDevState eq "" ) ;
$ residentDevPresence =
ReadingsVal ( AttrVal ( $ device , "msgRecipient" , "" ) ,
"presence" , "" )
if ( $ residentDevPresence eq "" ) ;
}
# device explicit
if (
(
$ residentDevState eq ""
|| $ residentDevPresence eq ""
)
&& ReadingsVal (
AttrVal ( $ device , "msgResidentsDev" , "" ) ,
"presence" , "-" ) ne "-"
)
{
$ residentDevState =
ReadingsVal (
AttrVal ( $ device , "msgResidentsDev" , "" ) ,
"state" , "" )
if ( $ residentDevState eq "" ) ;
$ residentDevPresence =
ReadingsVal (
AttrVal ( $ device , "msgResidentsDev" , "" ) ,
"presence" , "" )
if ( $ residentDevPresence eq "" ) ;
}
# global indirect
if (
(
$ residentDevState eq ""
|| $ residentDevPresence eq ""
)
&& ReadingsVal (
2015-10-18 13:09:15 +00:00
AttrVal ( $ globalDevName , "msgRecipient$typeUc" , "" ) ,
2015-09-24 12:19:46 +00:00
"presence" , "-" ) ne "-"
)
{
$ residentDevState =
ReadingsVal (
2015-10-18 13:09:15 +00:00
AttrVal ( $ globalDevName , "msgRecipient$typeUc" , "" ) ,
2015-09-24 12:19:46 +00:00
"state" , "" )
if ( $ residentDevState eq "" ) ;
$ residentDevPresence =
ReadingsVal (
2015-10-18 13:09:15 +00:00
AttrVal ( $ globalDevName , "msgRecipient$typeUc" , "" ) ,
2015-09-24 12:19:46 +00:00
"presence" , "" )
if ( $ residentDevPresence eq "" ) ;
}
# global indirect general
if (
(
$ residentDevState eq ""
|| $ residentDevPresence eq ""
)
2015-10-18 13:09:15 +00:00
&& ReadingsVal ( AttrVal ( $ globalDevName , "msgRecipient" , "" ) ,
2015-09-24 12:19:46 +00:00
"presence" , "-" ) ne "-"
)
{
$ residentDevState =
2015-10-18 13:09:15 +00:00
ReadingsVal ( AttrVal ( $ globalDevName , "msgRecipient" , "" ) ,
2015-09-24 12:19:46 +00:00
"state" , "" )
if ( $ residentDevState eq "" ) ;
$ residentDevPresence =
2015-10-18 13:09:15 +00:00
ReadingsVal ( AttrVal ( $ globalDevName , "msgRecipient" , "" ) ,
2015-09-24 12:19:46 +00:00
"presence" , "" )
if ( $ residentDevPresence eq "" ) ;
}
# global explicit
if (
(
$ residentDevState eq ""
|| $ residentDevPresence eq ""
)
&& ReadingsVal (
2015-10-18 13:09:15 +00:00
AttrVal ( $ globalDevName , "msgResidentsDev" , "" ) ,
2015-09-24 12:19:46 +00:00
"presence" , "-" ) ne "-"
)
{
$ residentDevState =
ReadingsVal (
2015-10-18 13:09:15 +00:00
AttrVal ( $ globalDevName , "msgResidentsDev" , "" ) ,
2015-09-24 12:19:46 +00:00
"state" , "" )
if ( $ residentDevState eq "" ) ;
$ residentDevPresence =
ReadingsVal (
2015-10-18 13:09:15 +00:00
AttrVal ( $ globalDevName , "msgResidentsDev" , "" ) ,
2015-09-24 12:19:46 +00:00
"presence" , "" )
if ( $ residentDevPresence eq "" ) ;
}
################################################################
### Send message
###
2015-10-06 09:10:01 +00:00
# user selected emergency priority text threshold
my $ prioThresGwEmg =
# look for direct
AttrVal (
$ device , "msgThPrioGwEmergency" ,
#look for indirect type
AttrVal (
AttrVal ( $ device , "msgRecipient$typeUc" , "" ) ,
"msgThPrioGwEmergency" ,
#look for indirect general
AttrVal (
AttrVal ( $ device , "msgRecipient" , "" ) ,
"msgThPrioGwEmergency" ,
# look for global direct
AttrVal (
2015-10-18 13:09:15 +00:00
$ globalDevName , "msgThPrioGwEmergency" ,
2015-10-06 09:10:01 +00:00
#look for global indirect type
AttrVal (
AttrVal (
2015-10-18 13:09:15 +00:00
$ globalDevName ,
2015-10-06 09:10:01 +00:00
"msgRecipient$typeUc" , ""
) ,
"msgThPrioGwEmergency" ,
#look for global indirect general
AttrVal (
AttrVal (
2015-10-18 13:09:15 +00:00
$ globalDevName , "msgRecipient" ,
2015-10-06 09:10:01 +00:00
""
) ,
"msgThPrioGwEmergency" ,
# default
"2"
)
)
)
)
)
)
;
2015-09-24 12:19:46 +00:00
my % gatewaysStatus ;
foreach my $ gatewayDevOr ( split /\|/ , $ gatewayDevs ) {
foreach my $ gatewayDev ( split /,/ , $ gatewayDevOr ) {
2015-10-18 16:33:00 +00:00
my $ subRecipient = "" ;
if ( $ gatewayDev =~ s/:(.*)// )
{
$ subRecipient = $ 1 ;
}
2015-09-24 12:19:46 +00:00
Log3 $ logDevice , 5 ,
2015-10-22 09:52:17 +00:00
"message $device: Trying to send message via gateway $gatewayDev to recipient $subRecipient" ;
2015-09-24 12:19:46 +00:00
##############
# check for gateway availability and set route status
#
my $ routeStatus = "OK" ;
if ( $ type [ $ i ] ne "mail"
&& ! defined ( $ defs { $ gatewayDev } )
&& $ deviceType eq "device" )
{
$ routeStatus = "UNDEFINED" ;
}
elsif ( $ type [ $ i ] ne "mail"
&& AttrVal ( $ gatewayDev , "disable" , "0" ) eq
"1" )
{
$ routeStatus = "DISABLED" ;
}
elsif (
$ type [ $ i ] ne "mail"
&& (
2015-10-12 22:18:10 +00:00
ReadingsVal (
$ gatewayDev , "power" ,
"on"
) eq "off"
|| ReadingsVal (
$ gatewayDev , "presence" ,
"present"
) eq "absent"
|| ReadingsVal (
$ gatewayDev , "presence" ,
"appeared"
) eq "disappeared"
|| ReadingsVal (
$ gatewayDev , "state" ,
"present"
) eq "absent"
|| ReadingsVal (
$ gatewayDev , "state" ,
"connected"
) eq "unauthorized"
|| ReadingsVal (
$ gatewayDev , "state" ,
"connected"
) eq "disconnected"
|| ReadingsVal (
$ gatewayDev , "state" ,
"reachable"
) eq "unreachable"
|| ReadingsVal (
$ gatewayDev , "available" ,
2015-09-24 12:19:46 +00:00
"1"
2015-10-12 22:18:10 +00:00
) eq "0"
|| ReadingsVal (
$ gatewayDev , "available" ,
"yes"
) eq "no"
|| ReadingsVal (
$ gatewayDev , "reachable" ,
"1"
) eq "0"
|| ReadingsVal (
$ gatewayDev , "reachable" ,
"yes"
) eq "no"
2015-09-24 12:19:46 +00:00
)
)
{
$ routeStatus = "UNAVAILABLE" ;
}
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" ;
}
2015-10-06 15:43:40 +00:00
elsif ( $ type [ $ i ] ne "push"
&& $ type [ $ i ] ne "mail"
&& $ residentDevState eq "asleep" )
{
$ routeStatus = "USER_ASLEEP" ;
}
2015-09-24 12:19:46 +00:00
# enforce by user request
if (
(
$ routeStatus eq "USER_DISABLED"
|| $ routeStatus eq "USER_ABSENT"
2015-10-06 15:43:40 +00:00
|| $ routeStatus eq "USER_ASLEEP"
2015-09-24 12:19:46 +00:00
)
&& ( $ forceType == 1 || $ forceDevice == 1 )
)
{
$ routeStatus = "OK_ENFORCED" ;
}
# enforce by priority
if (
(
$ routeStatus eq "USER_DISABLED"
|| $ routeStatus eq "USER_ABSENT"
2015-10-06 15:43:40 +00:00
|| $ routeStatus eq "USER_ASLEEP"
2015-09-24 12:19:46 +00:00
)
2015-10-06 09:10:01 +00:00
&& $ loopPriority >= $ prioThresGwEmg
2015-09-24 12:19:46 +00:00
)
{
$ routeStatus = "OK_EMERGENCY" ;
}
# add location status
if ( $ useLocation == 2 ) {
$ routeStatus . = "+LOCATION-UNAVAILABLE" ;
}
elsif ( $ useLocation == 1 ) {
$ routeStatus . = "+LOCATION" ;
}
2015-10-12 22:18:10 +00:00
my $ gatewayType = $ type [ $ i ] eq "mail" ? "fhemMsgMail" : $ defs { $ gatewayDev } { TYPE } ;
my $ defTitle = defined ( $ settings - > { $ type [ $ i ] } { title } ) ? $ settings - > { $ type [ $ i ] } { title } : "System Message" ;
$ defTitle = $ cmdSchema - > { $ type [ $ i ] } { $ gatewayType } { defaultValues } { $ priorityCat } { TITLE }
if ( defined ( $ cmdSchema - > { $ type [ $ i ] } { $ gatewayType } { defaultValues } { $ priorityCat } { TITLE } ) && $ priorityCat ne "" ) ;
$ defTitle = $ cmdSchema - > { $ type [ $ i ] } { $ gatewayType } { defaultValues } { Normal } { TITLE }
if ( defined ( $ cmdSchema - > { $ type [ $ i ] } { $ gatewayType } { defaultValues } { Normal } { TITLE } ) && $ priorityCat eq "" ) ;
# use title from device, global or internal default
my $ loopTitle ;
$ loopTitle = $ title if ( $ title ne "-" ) ;
$ loopTitle =
# look for direct high
AttrVal (
$ device , "msgTitle$typeUc$priorityCat" ,
# look for indirect high
AttrVal (
AttrVal ( $ device , "msgRecipient$typeUc" , "" ) ,
"msgTitle$typeUc$priorityCat" ,
#look for indirect general high
AttrVal (
AttrVal ( $ device , "msgRecipient" , "" ) ,
"msgTitle$typeUc$priorityCat" ,
# look for global direct high
AttrVal (
2015-10-18 13:09:15 +00:00
$ globalDevName , "msgTitle$typeUc$priorityCat" ,
2015-10-12 22:18:10 +00:00
# look for global indirect high
AttrVal (
AttrVal (
2015-10-18 13:09:15 +00:00
$ globalDevName , "msgRecipient$typeUc" ,
2015-10-12 22:18:10 +00:00
""
) ,
"msgTitle$typeUc$priorityCat" ,
#look for global indirect general high
AttrVal (
AttrVal (
2015-10-18 13:09:15 +00:00
$ globalDevName , "msgRecipient" ,
2015-10-12 22:18:10 +00:00
""
) ,
"msgTitle$typeUc$priorityCat" ,
# default
$ defTitle
)
)
)
)
)
) if ( $ title eq "-" ) ;
if ( $ type [ $ i ] eq "mail" && $ priorityCat ne "" ) {
$ loopTitle = "[$priorityCat] $loopTitle" ;
}
my $ loopMsg = $ msg ;
if ( $ catchall == 1 ) {
$ loopTitle = "Fw: $loopTitle" ;
if ( $ type [ $ i ] eq "mail" ) {
$ loopMsg . =
"\n\n-- \nMail catched from device $device" ;
}
else {
$ loopMsg . = " ### (Catched from device $device)" ;
}
}
# correct message format
#
$ loopMsg =~ s/\n/<br \/>/gi ;
$ loopMsg =~ s/((|(\d+)| )\|\w+\|( |))/\n\n/gi
if ( $ type [ $ i ] ne "audio" ) ; # Remove Sonos Speak commands
# use command from device, global or internal default
my $ defCmd = "" ;
$ defCmd = $ cmdSchema - > { $ type [ $ i ] } { $ gatewayType } { $ priorityCat }
if ( defined ( $ cmdSchema - > { $ type [ $ i ] } { $ gatewayType } { $ priorityCat } ) && $ priorityCat ne "" ) ;
$ defCmd = $ cmdSchema - > { $ type [ $ i ] } { $ gatewayType } { Normal }
if ( defined ( $ cmdSchema - > { $ type [ $ i ] } { $ gatewayType } { Normal } ) && $ priorityCat eq "" ) ;
2015-09-24 12:19:46 +00:00
my $ cmd =
# gateway device
AttrVal (
$ gatewayDev , "msgCmd$typeUc$priorityCat" ,
# 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 (
2015-10-18 13:09:15 +00:00
$ globalDevName ,
2015-09-24 12:19:46 +00:00
"msgCmd$typeUc$priorityCat" ,
# look for global indirect
AttrVal (
AttrVal (
2015-10-18 13:09:15 +00:00
$ globalDevName ,
2015-09-24 12:19:46 +00:00
"msgRecipient$typeUc" ,
""
) ,
"msgCmd$typeUc$priorityCat" ,
#look for global indirect general
AttrVal (
AttrVal (
2015-10-18 13:09:15 +00:00
$ globalDevName ,
2015-09-24 12:19:46 +00:00
"msgRecipient" ,
""
) ,
"msgCmd$typeUc$priorityCat" ,
# internal
$ defCmd
)
)
)
)
)
)
) ;
2015-10-12 22:18:10 +00:00
if ( $ cmd eq "" ) {
Log3 $ logDevice , 4 , "$gatewayDev: Unknown command schema for gateway device type $gatewayType. Use manual definition by userattr msgCmd*" ;
$ return . = "$gatewayDev: Unknown command schema for gateway device type $gatewayType. Use manual definition by userattr msgCmd*\n" ;
next ;
}
$ cmd =~ s/%DEVICE%/$gatewayDev/gi ;
$ cmd =~ s/%PRIORITY%/$loopPriority/gi ;
$ cmd =~ s/%TITLE%/$loopTitle/gi ;
$ cmd =~ s/%MSG%/$loopMsg/gi ;
2015-10-18 16:33:00 +00:00
$ cmd =~ s/%RECIPIENT%/$subRecipient/gi if ( $ subRecipient ne "" ) ;
2015-10-12 22:18:10 +00:00
# advanced options from message
if ( ref ( $ advanced ) eq "ARRAY" ) {
for my $ item ( @$ advanced ) {
for my $ key ( keys ( %$ item ) ) {
my $ val = $ item - > { $ key } ;
$ cmd =~ s/%$key%/$val/gi ;
}
}
}
# advanced options from command schema hash
if ( $ priorityCat ne "" && defined ( $ cmdSchema - > { $ type [ $ i ] } { $ gatewayType } { defaultValues } { $ priorityCat } ) ) {
for my $ item ( $ cmdSchema - > { $ type [ $ i ] } { $ gatewayType } { defaultValues } { $ priorityCat } ) {
for my $ key ( keys ( %$ item ) ) {
my $ val = $ item - > { $ key } ;
$ cmd =~ s/%$key%/$val/gi ;
}
}
}
elsif ( $ priorityCat eq "" && defined ( $ cmdSchema - > { $ type [ $ i ] } { $ gatewayType } { defaultValues } { Normal } ) ) {
for my $ item ( $ cmdSchema - > { $ type [ $ i ] } { $ gatewayType } { defaultValues } { Normal } ) {
for my $ key ( keys ( %$ item ) ) {
my $ val = $ item - > { $ key } ;
$ cmd =~ s/%$key%/$val/gi ;
}
}
}
2015-09-24 12:19:46 +00:00
$ sentCounter + + ;
if ( $ routeStatus =~ /^OK\w*/ ) {
2015-10-12 22:18:10 +00:00
my $ error = 0 ;
2015-09-24 12:19:46 +00:00
# run command
2015-10-12 22:18:10 +00:00
undef $@ ;
if ( $ cmd =~ s/^[ \t]*\{|\}[ \t]*$//gi ) {
$ cmd =~ s/@\w+/\\$&/gi ;
2015-09-24 12:19:46 +00:00
Log3 $ logDevice , 5 ,
2015-10-22 09:52:17 +00:00
"message $device: $type[$i] route command (Perl): $cmd" ;
2015-09-24 12:19:46 +00:00
eval $ cmd ;
2015-10-12 22:18:10 +00:00
if ( $@ ) {
$ error = 1 ;
$ return . = "$gatewayDev: $@\n" ;
}
2015-09-24 12:19:46 +00:00
}
else {
Log3 $ logDevice , 5 ,
2015-10-22 09:52:17 +00:00
"message $device: $type[$i] route command (fhem): $cmd" ;
2015-09-24 12:19:46 +00:00
fhem $ cmd ;
2015-10-12 22:18:10 +00:00
if ( $@ ) {
$ error = 1 ;
$ return . = "$gatewayDev: $@\n" ;
}
2015-09-24 12:19:46 +00:00
}
2015-10-12 22:18:10 +00:00
$ routeStatus = "ERROR" if ( $ error == 1 ) ;
Log3 $ logDevice , 3 ,
2015-10-22 09:52:17 +00:00
"message $device: ID=$messageID.$sentCounter TYPE=$type[$i] ROUTE=$gatewayDev RECIPIENT=$subRecipient STATUS=$routeStatus PRIORITY=$loopPriority($priorityCat) TITLE='$loopTitle' MSG='$msg'"
2015-10-19 11:58:11 +00:00
if ( $ priorityCat ne "" && $ subRecipient ne "" ) ;
2015-10-12 22:18:10 +00:00
Log3 $ logDevice , 3 ,
2015-10-22 09:52:17 +00:00
"message $device: ID=$messageID.$sentCounter TYPE=$type[$i] ROUTE=$gatewayDev RECIPIENT=$subRecipient STATUS=$routeStatus PRIORITY=$loopPriority TITLE='$loopTitle' MSG='$msg'"
2015-10-19 11:58:11 +00:00
if ( $ priorityCat eq "" && $ subRecipient ne "" ) ;
Log3 $ logDevice , 3 ,
2015-10-22 09:52:17 +00:00
"message $device: ID=$messageID.$sentCounter TYPE=$type[$i] ROUTE=$gatewayDev STATUS=$routeStatus PRIORITY=$loopPriority($priorityCat) TITLE='$loopTitle' MSG='$msg'"
2015-10-19 11:58:11 +00:00
if ( $ priorityCat ne "" && $ subRecipient eq "" ) ;
Log3 $ logDevice , 3 ,
2015-10-22 09:52:17 +00:00
"message $device: ID=$messageID.$sentCounter TYPE=$type[$i] ROUTE=$gatewayDev STATUS=$routeStatus PRIORITY=$loopPriority TITLE='$loopTitle' MSG='$msg'"
2015-10-19 11:58:11 +00:00
if ( $ priorityCat eq "" && $ subRecipient eq "" ) ;
2015-10-12 22:18:10 +00:00
$ messageSent = 1 if ( $ error == 0 ) ;
$ messageSentDev = 1 if ( $ error == 0 ) ;
$ gatewaysStatus { $ gatewayDev } = $ routeStatus ;
2015-09-24 12:19:46 +00:00
}
elsif ( $ routeStatus eq "UNAVAILABLE"
|| $ routeStatus eq "UNDEFINED" )
{
Log3 $ logDevice , 3 ,
2015-10-22 09:52:17 +00:00
"message $device: ID=$messageID.$sentCounter TYPE=$type[$i] ROUTE=$gatewayDev RECIPIENT=$subRecipient STATUS=$routeStatus PRIORITY=$loopPriority TITLE='$loopTitle' '$msg'" if ( $ subRecipient ne "" ) ;
2015-10-19 11:58:11 +00:00
Log3 $ logDevice , 3 ,
2015-10-22 09:52:17 +00:00
"message $device: ID=$messageID.$sentCounter TYPE=$type[$i] ROUTE=$gatewayDev STATUS=$routeStatus PRIORITY=$loopPriority TITLE='$loopTitle' '$msg'" if ( $ subRecipient eq "" ) ;
2015-09-24 12:19:46 +00:00
$ gatewaysStatus { $ gatewayDev } = $ routeStatus ;
}
else {
Log3 $ logDevice , 3 ,
2015-10-22 09:52:17 +00:00
"message $device: ID=$messageID.$sentCounter TYPE=$type[$i] ROUTE=$gatewayDev RECIPIENT=$subRecipient STATUS=$routeStatus PRIORITY=$loopPriority TITLE='$loopTitle' '$msg'" if ( $ subRecipient ne "" ) ;
2015-10-19 11:58:11 +00:00
Log3 $ logDevice , 3 ,
2015-10-22 09:52:17 +00:00
"message $device: ID=$messageID.$sentCounter TYPE=$type[$i] ROUTE=$gatewayDev STATUS=$routeStatus PRIORITY=$loopPriority TITLE='$loopTitle' '$msg'" if ( $ subRecipient eq "" ) ;
2015-09-24 12:19:46 +00:00
$ messageSent = 2 if ( $ messageSent != 1 ) ;
$ messageSentDev = 2 if ( $ messageSentDev != 1 ) ;
$ gatewaysStatus { $ gatewayDev } = $ routeStatus ;
}
}
last if ( $ messageSentDev == 1 ) ;
}
if ( $ catchall == 0 ) {
if ( ! defined ( $ sentTypesPerDevice { $ device } ) ) {
$ sentTypesPerDevice { $ device } = "" ;
}
else {
$ sentTypesPerDevice { $ device } . = " " ;
}
$ sentTypesPerDevice { $ device } . =
$ type [ $ i ] . ":" . $ messageSentDev ;
}
else {
if ( ! defined ( $ sentTypesPerDevice { $ device } ) ) {
2015-10-18 13:09:15 +00:00
$ sentTypesPerDevice { $ globalDevName } = "" ;
2015-09-24 12:19:46 +00:00
}
else {
2015-10-18 13:09:15 +00:00
$ sentTypesPerDevice { $ globalDevName } . = " " ;
2015-09-24 12:19:46 +00:00
}
2015-10-18 13:09:15 +00:00
$ sentTypesPerDevice { $ globalDevName } . =
2015-09-24 12:19:46 +00:00
$ type [ $ i ] . ":" . $ messageSentDev ;
}
# update device readings
my $ readingsDev = $ defs { $ device } ;
2015-10-18 13:09:15 +00:00
$ readingsDev = $ defs { $ globalDevName } if ( $ catchall == 1 ) ;
2015-09-24 12:19:46 +00:00
readingsBeginUpdate ( $ readingsDev ) ;
readingsBulkUpdate ( $ readingsDev , "fhemMsg" . $ typeUc ,
2015-10-12 22:18:10 +00:00
$ msg ) ;
2015-09-24 12:19:46 +00:00
readingsBulkUpdate ( $ readingsDev ,
2015-10-12 22:18:10 +00:00
"fhemMsg" . $ typeUc . "Title" , $ title ) ;
2015-09-24 12:19:46 +00:00
readingsBulkUpdate ( $ readingsDev ,
"fhemMsg" . $ typeUc . "Prio" ,
$ loopPriority ) ;
my $ gwStates = "" ;
while ( ( my $ gwName , my $ gwState ) = each % gatewaysStatus )
{
$ gwStates . = " " if $ gwStates ne "" ;
$ gwStates . = "$gwName:$gwState" ;
}
readingsBulkUpdate ( $ readingsDev ,
"fhemMsg" . $ typeUc . "Gw" , $ gwStates ) ;
readingsBulkUpdate ( $ readingsDev ,
"fhemMsg" . $ typeUc . "State" ,
$ messageSentDev ) ;
################################################################
### Implicit forwards based on priority or presence
###
# no implicit escalations for type mail
next if ( $ type [ $ i ] eq "mail" ) ;
# Skip if typeOr is defined
# and this is not the last type entry
# TODO: bei mehreren gleichzeitigen Typen (and-Definition)?
if ( $ messageSentDev != 1
&& $ hasTypeOr == 1
&& $ isTypeOr < scalar ( grep { defined $ _ } @ typesOr ) )
{
Log3 $ logDevice , 4 ,
2015-10-22 09:52:17 +00:00
"message $device: Skipping implicit forward due to typesOr definition" ;
2015-09-24 12:19:46 +00:00
# remove recipient from list to avoid
# other interaction when using recipientOr in parallel
if ( $ hasRecipientOr == 1
&& $ isRecipientOr <
scalar ( grep { defined $ _ } @ recipientsOr ) )
{
my $ regex1 =
2015-10-12 22:18:10 +00:00
"\\s*!?@?" . $ device . "[,|]" ; # at the beginning
2015-09-24 12:19:46 +00:00
my $ regex2 =
2015-10-12 22:18:10 +00:00
"[,|]!?@?" . $ device . "\\s*" ; # at the end
2015-09-24 12:19:46 +00:00
my $ regex3 =
",!?@?"
. $ device
. "," ; # in the middle with comma
my $ regex4 =
"[\|,]!?@?"
. $ device
. "[\|,]" ; # in the middle with pipe and/or comma
$ recipients =~ s/^$regex1// ;
2015-10-12 22:18:10 +00:00
$ recipients =~ s/$regex2$/|/gi ;
$ recipients =~ s/$regex3/,/gi ;
$ recipients =~ s/$regex4/|/gi ;
2015-09-24 12:19:46 +00:00
}
next ;
}
# Skip if recipientOr is defined
# and this is not the last device entry
# TODO: bei mehreren gleichzeitigen Empfängern
# (and-Definition)?
if ( $ messageSentDev != 1
&& $ hasRecipientOr == 1
&& $ isRecipientOr <
scalar ( grep { defined $ _ } @ recipientsOr ) )
{
Log3 $ logDevice , 4 ,
2015-10-22 09:52:17 +00:00
"message $device: Skipping implicit forward due to recipientOr definition" ;
2015-09-24 12:19:46 +00:00
next ;
}
# priority forward thresholds
#
### emergency
my $ msgFwPrioEmergency =
# look for direct
AttrVal (
$ device , "msgFwPrioEmergency$typeUc" ,
#look for indirect
AttrVal (
AttrVal ( $ device , "msgRecipient$typeUc" , "" ) ,
"msgFwPrioEmergency$typeUc" ,
#look for indirect general
AttrVal (
AttrVal ( $ device , "msgRecipient" , "" ) ,
"msgFwPrioEmergency$typeUc" ,
# default
2
)
)
) ;
### absent
my $ msgFwPrioAbsent =
# look for direct
AttrVal (
$ device , "msgFwPrioAbsent$typeUc" ,
#look for indirect
AttrVal (
AttrVal ( $ device , "msgRecipient$typeUc" , "" ) ,
"msgFwPrioAbsent$typeUc" ,
#look for indirect general
AttrVal (
AttrVal ( $ device , "msgRecipient" , "" ) ,
"msgFwPrioAbsent$typeUc" ,
# default
0
)
)
) ;
### gone
my $ msgFwPrioGone =
# look for direct
AttrVal (
$ device , "msgFwPrioGone$typeUc" ,
#look for indirect
AttrVal (
AttrVal ( $ device , "msgRecipient$typeUc" , "" ) ,
"msgFwPrioGone$typeUc" ,
#look for indirect general
AttrVal (
AttrVal ( $ device , "msgRecipient" , "" ) ,
"msgFwPrioGone$typeUc" ,
# default
1
)
)
) ;
Log3 $ logDevice , 5 ,
2015-10-22 09:52:17 +00:00
"message $device: Implicit forwards: recipient presence=$residentDevPresence state=$residentDevState"
2015-09-24 12:19:46 +00:00
if ( $ residentDevPresence ne ""
|| $ residentDevState ne "" ) ;
2015-10-12 22:18:10 +00:00
my $ fw_gwUnavailable = defined ( $ settings - > { $ type [ $ i ] } { typeEscalation } { gwUnavailable } ) ? $ settings - > { $ type [ $ i ] } { typeEscalation } { gwUnavailable } : "" ;
my $ fw_emergency = defined ( $ settings - > { $ type [ $ i ] } { typeEscalation } { emergency } ) ? $ settings - > { $ type [ $ i ] } { typeEscalation } { emergency } : "" ;
my $ fw_residentAbsent = defined ( $ settings - > { $ type [ $ i ] } { typeEscalation } { residentAbsent } ) ? $ settings - > { $ type [ $ i ] } { typeEscalation } { residentAbsent } : "" ;
my $ fw_residentGone = defined ( $ settings - > { $ type [ $ i ] } { typeEscalation } { residentGone } ) ? $ settings - > { $ type [ $ i ] } { typeEscalation } { residentGone } : "" ;
2015-09-24 12:19:46 +00:00
# Forward message
# if no gateway device for this type was available
if ( $ messageSentDev == 0
2015-10-12 22:18:10 +00:00
&& $ fw_gwUnavailable ne ""
2015-09-24 12:19:46 +00:00
&& ! ( $ fw_gwUnavailable ~ ~ @ type )
&& $ routes { $ fw_gwUnavailable } == 1 )
{
Log3 $ logDevice , 4 ,
2015-10-22 09:52:17 +00:00
"message $device: Implicit forwards: No $type[$i] gateway device available for recipient $device ($gatewayDevs). Trying alternative message type "
2015-09-24 12:19:46 +00:00
. $ fw_gwUnavailable ;
push @ type , $ fw_gwUnavailable ;
$ forwarded . = "," . $ type [ $ i ] . ">" . $ fw_gwUnavailable
if ( $ forwarded ne "" ) ;
$ forwarded . = $ type [ $ i ] . ">" . $ fw_gwUnavailable
if ( $ forwarded eq "" ) ;
}
# Forward message
# if emergency priority
if ( $ loopPriority >= $ msgFwPrioEmergency
2015-10-12 22:18:10 +00:00
&& $ fw_emergency ne ""
2015-09-24 12:19:46 +00:00
&& ! ( $ fw_emergency ~ ~ @ type )
&& $ routes { $ fw_emergency } == 1 )
{
Log3 $ logDevice , 4 ,
2015-10-22 09:52:17 +00:00
"message $device: Implicit forwards: Escalating high priority $type[$i] message via "
2015-09-24 12:19:46 +00:00
. $ fw_emergency ;
push @ type , $ fw_emergency ;
$ forwarded . = "," . $ type [ $ i ] . ">" . $ fw_emergency
if ( $ forwarded ne "" ) ;
$ forwarded . = $ type [ $ i ] . ">" . $ fw_emergency
if ( $ forwarded eq "" ) ;
}
# Forward message
# if high priority and residents are constantly not at home
if ( $ residentDevPresence eq "absent"
&& $ loopPriority >= $ msgFwPrioGone
2015-10-12 22:18:10 +00:00
&& $ fw_residentGone ne ""
2015-09-24 12:19:46 +00:00
&& ! ( $ fw_residentGone ~ ~ @ type )
&& $ routes { $ fw_residentGone } == 1 )
{
Log3 $ logDevice , 4 ,
2015-10-22 09:52:17 +00:00
"message $device: Implicit forwards: Escalating high priority $type[$i] message via "
2015-09-24 12:19:46 +00:00
. $ fw_residentGone ;
push @ type , $ fw_residentGone ;
$ forwarded . = "," . $ type [ $ i ] . ">" . $ fw_residentGone
if ( $ forwarded ne "" ) ;
$ forwarded . = $ type [ $ i ] . ">" . $ fw_residentGone
if ( $ forwarded eq "" ) ;
}
# Forward message
# if priority is normal or higher and residents
# are not at home but nearby
if ( $ residentDevState eq "absent"
&& $ loopPriority >= $ msgFwPrioAbsent
2015-10-12 22:18:10 +00:00
&& $ fw_residentAbsent ne ""
2015-09-24 12:19:46 +00:00
&& ! ( $ fw_residentAbsent ~ ~ @ type )
&& $ routes { $ fw_residentAbsent } == 1 )
{
Log3 $ logDevice , 4 ,
2015-10-22 09:52:17 +00:00
"message $device: Implicit forwards: Escalating $type[$i] message via "
2015-09-24 12:19:46 +00:00
. $ fw_residentAbsent
. " due to absence" ;
push @ type , $ fw_residentAbsent ;
$ forwarded . = "," . $ type [ $ i ] . ">" . $ fw_residentAbsent
if ( $ forwarded ne "" ) ;
$ forwarded . = $ type [ $ i ] . ">" . $ fw_residentAbsent
if ( $ forwarded eq "" ) ;
}
}
last if ( $ messageSent == 1 ) ;
$ isRecipientOr + + ;
}
}
last if ( $ messageSent == 1 ) ;
$ isTypeOr + + ;
}
# finalize device readings
while ( ( my $ device , my $ types ) = each % sentTypesPerDevice ) {
readingsBulkUpdate ( $ defs { $ device } , "fhemMsgStateTypes" , $ types )
if ( $ forwarded eq "" ) ;
readingsBulkUpdate ( $ defs { $ device } , "fhemMsgStateTypes" ,
$ types . " forwards:" . $ forwarded )
if ( $ forwarded ne "" ) ;
readingsBulkUpdate ( $ defs { $ device } , "fhemMsgState" , $ messageSent ) ;
readingsEndUpdate ( $ defs { $ device } , 1 ) ;
}
if ( $ messageSent == 1 && $ return ne "" ) {
$ return . = "However, message was still sent to some recipients!" ;
}
if ( $ messageSent == 2 ) {
$ return . =
"FATAL ERROR: Message NOT sent. No gateway device was available." ;
}
return $ return ;
}
1 ;
= pod
= begin html
2015-10-22 09:52:17 +00:00
< a name = "message" > </a>
<h3> message </h3>
2015-09-24 12:19:46 +00:00
<ul>
2015-10-22 09:52:17 +00:00
<code> message [ & lt ; type & gt ; ] [ & lt ; @ device & gt ; | & lt ; e - mail address & gt ; ] [ & lt ; priority & gt ; ] [ | & lt ; title & gt ; | ] & lt ; message & gt ; </code>
2015-09-24 12:19:46 +00:00
<br>
<br>
2015-10-22 09:52:17 +00:00
No documentation here yet , sorry . <br>
2015-09-24 12:19:46 +00:00
< a href = "http://forum.fhem.de/index.php/topic,39983.0.html" > FHEM Forum </a>
</ul>
= end html
= begin html_DE
2015-10-22 09:52:17 +00:00
< a name = "message" > </a>
<h3> message </h3>
2015-09-24 12:19:46 +00:00
<ul>
2015-10-22 09:52:17 +00:00
<code> message [ & lt ; type & gt ; ] [ & lt ; @ device & gt ; | & lt ; e - mail address & gt ; ] [ & lt ; priority & gt ; ] [ | & lt ; title & gt ; | ] & lt ; message & gt ; </code>
2015-09-24 12:19:46 +00:00
<br>
<br>
2015-10-22 09:52:17 +00:00
Bisher keine Dokumentation hier , sorry . <br>
2015-09-24 12:19:46 +00:00
< a href = "http://forum.fhem.de/index.php/topic,39983.0.html" > FHEM Forum </a>
</ul>
= end html_DE
= cut