From a9a1e8aea4bd99264ae222dc88ecf5bd84dfc446 Mon Sep 17 00:00:00 2001 From: loredo Date: Mon, 20 Mar 2017 16:31:30 +0000 Subject: [PATCH] 70_Pushover: add support to cancel confirmation request git-svn-id: https://svn.fhem.de/fhem/trunk@13748 2b470e98-0d58-463d-a4d8-8e2adae1ed80 --- fhem/FHEM/70_Pushover.pm | 255 +++++++++++++++++++++++++++------------ 1 file changed, 177 insertions(+), 78 deletions(-) diff --git a/fhem/FHEM/70_Pushover.pm b/fhem/FHEM/70_Pushover.pm index a219485f1..541ad17cb 100644 --- a/fhem/FHEM/70_Pushover.pm +++ b/fhem/FHEM/70_Pushover.pm @@ -13,8 +13,6 @@ use HttpUtils; use SetExtensions; use Encode; -my %sets = ( "msg" => 1, "glance" => 1 ); - #------------------------------------------------------------------------------ sub Pushover_Initialize($$) { my ($hash) = @_; @@ -128,12 +126,23 @@ sub Pushover_Set($@) { my ( $hash, $name, $cmd, @args ) = @_; my ( $a, $h ) = parseParams( join " ", @args ); - if ( !defined( $sets{$cmd} ) ) { - return - "Unknown argument " - . $cmd - . ", choose one of " - . join( " ", sort keys %sets ); + unless ( $cmd =~ /^(msg|msgCancel|glance)$/i ) { + my $usage = "Unknown argument $cmd, choose one of msg glance"; + + sort keys %{ $hash->{READINGS} }; + my $cancelIds; + while ( my ( $key, $value ) = each %{ $hash->{READINGS} } ) { + if ( defined( $value->{VAL} ) + && $value->{VAL} ne "" + && $key =~ /^cbCancelId_(\d+)$/ ) + { + $cancelIds .= "," if ($cancelIds); + $cancelIds .= $value->{VAL}; + } + } + + $usage .= " msgCancel:" . $cancelIds if ($cancelIds); + return $usage; } return "Unable to send message: Device is disabled" @@ -157,6 +166,9 @@ sub Pushover_Set($@) { return Pushover_SetMessage( $hash, @args ) if ( $cmd eq 'msg' ); + + return Pushover_CancelMessage( $hash, @args ) + if ( lc($cmd) eq 'msgcancel' ); } #------------------------------------------------------------------------------ @@ -558,6 +570,10 @@ sub Pushover_ReceiveCommand($$$) { if ( defined $return->{receipt} ) { readingsBulkUpdate( $hash, "cb_" . $values->{cbNr}, $return->{receipt} ); + readingsBulkUpdate( $hash, + "cbCancelId_" . $values->{cbNr}, + $values->{cancel_id} ) + if ( defined( $values->{cancel_id} ) ); } else { readingsBulkUpdate( $hash, "cb_" . $values->{cbNr}, @@ -577,6 +593,32 @@ sub Pushover_ReceiveCommand($$$) { } } + # receipts/$receipt/cancel.json + elsif ( $service =~ /^receipts\/(.*)\/cancel.json$/ ) { + my $receipt = $1; + + while ( my ( $key, $value ) = each %{ $hash->{READINGS} } ) { + if ( $key =~ /^cb_(\d+)$/ + && defined( $value->{VAL} ) + && $value->{VAL} eq $receipt ) + { + my $rAct = "cbAct_" . $1; + my $rAck = "cbAck_" . $1; + my $rAckAt = "cbAckAt_" . $1; + my $rAckBy = "cbAckBy_" . $1; + my $rCancelId = "cbCancelId_" . $1; + + if ( $param->{code} == 200 ) { + readingsBulkUpdate( $hash, $rAck, "1" ); + readingsBulkUpdate( $hash, $rAckAt, int( time() ) ); + readingsBulkUpdate( $hash, $rAckBy, "aborted" ); + delete $hash->{READINGS}{$rCancelId} + if ( defined( $hash->{READINGS}{$rCancelId} ) ); + } + } + } + } + # glances.json elsif ( $service eq "glances.json" ) { @@ -683,14 +725,13 @@ sub Pushover_ValidateUser ($;$) { } elsif ( $device ne "" ) { - Pushover_SendCommand( $hash, "users/validate.json", "device=$device" ); + return Pushover_SendCommand( $hash, "users/validate.json", + "device=$device" ); } else { - Pushover_SendCommand( $hash, "users/validate.json" ); + return Pushover_SendCommand( $hash, "users/validate.json" ); } - - return; } #------------------------------------------------------------------------------ @@ -949,30 +990,30 @@ sub Pushover_SetMessage { } # cleanup callback readings - my $revReadings; - while ( ( $key, $value ) = each %{ $hash->{READINGS} } ) { - if ( $key =~ /^cb_\d+$/ ) { - my @rBase = split( "_", $key ); - my $rTit = "cbTitle_" . $rBase[1]; - my $rMsg = "cbMsg_" . $rBase[1]; - my $rPrio = "cbPrio_" . $rBase[1]; - my $rAct = "cbAct_" . $rBase[1]; - my $rAck = "cbAck_" . $rBase[1]; - my $rAckAt = "cbAckAt_" . $rBase[1]; - my $rAckBy = "cbAckBy_" . $rBase[1]; - my $rDev = "cbDev_" . $rBase[1]; + keys %{ $hash->{READINGS} }; + while ( my ( $key, $value ) = each %{ $hash->{READINGS} } ) { + if ( $key =~ /^cb_(\d+)$/ ) { + my $rTit = "cbTitle_" . $1; + my $rMsg = "cbMsg_" . $1; + my $rPrio = "cbPrio_" . $1; + my $rAct = "cbAct_" . $1; + my $rAck = "cbAck_" . $1; + my $rAckAt = "cbAckAt_" . $1; + my $rAckBy = "cbAckBy_" . $1; + my $rCancelId = "cbCancelId_" . $1; + my $rDev = "cbDev_" . $1; Log3 $name, 5, "Pushover $name: checking to clean up " . $hash->{NAME} . " $key: time=" - . $rBase[1] . " ack=" + . $1 . " ack=" . ReadingsVal( $name, $rAck, "-" ) . " curTime=" . int( time() ); - if ( ReadingsVal( $name, $rAck, 0 ) == 1 - || $rBase[1] <= int( time() ) ) + if ( ReadingsVal( $name, $rAck, "0" ) eq "1" + || $1 <= int( time() ) ) { delete $hash->{READINGS}{$key}; delete $hash->{READINGS}{$rTit}; @@ -981,25 +1022,22 @@ sub Pushover_SetMessage { delete $hash->{READINGS}{$rAck}; delete $hash->{READINGS}{$rDev}; - if ( defined( $hash->{READINGS}{$rAct} ) ) { - delete $hash->{READINGS}{$rAct}; - } - if ( defined( $hash->{READINGS}{$rAckAt} ) ) { - delete $hash->{READINGS}{$rAckAt}; - } - if ( defined( $hash->{READINGS}{$rAckBy} ) ) { - delete $hash->{READINGS}{$rAckBy}; - } + delete $hash->{READINGS}{$rAct} + if ( defined( $hash->{READINGS}{$rAct} ) ); + delete $hash->{READINGS}{$rAckAt} + if ( defined( $hash->{READINGS}{$rAckAt} ) ); + delete $hash->{READINGS}{$rAckBy} + if ( defined( $hash->{READINGS}{$rAckBy} ) ); + delete $hash->{READINGS}{$rCancelId} + if ( defined( $hash->{READINGS}{$rCancelId} ) ); Log3 $name, 4, - "Pushover $name: cleaned up expired receipt " . $rBase[1]; + "Pushover $name: cleaned up expired receipt " . $1; } } } - Pushover_SendCommand( $hash, "messages.json", $body, %values ); - - return; + return Pushover_SendCommand( $hash, "messages.json", $body, %values ); } else { @@ -1053,6 +1091,8 @@ sub Pushover_SetMessage2 ($$$$) { $values{url_title} = $h->{url_title} ? $h->{url_title} : ""; $values{action} = $h->{action} ? $h->{action} : ( $h->{url} ? $h->{url} : "" ); + $values{cancel_id} = $h->{cancel_id} + if ( defined( $h->{cancel_id} ) && $values{priority} ge "2" ); # glances only if ( $cmd eq "glance" ) { @@ -1276,30 +1316,30 @@ sub Pushover_SetMessage2 ($$$$) { } # cleanup callback readings - my $revReadings; - while ( ( $key, $value ) = each %{ $hash->{READINGS} } ) { - if ( $key =~ /^cb_\d+$/ ) { - my @rBase = split( "_", $key ); - my $rTit = "cbTitle_" . $rBase[1]; - my $rMsg = "cbMsg_" . $rBase[1]; - my $rPrio = "cbPrio_" . $rBase[1]; - my $rAct = "cbAct_" . $rBase[1]; - my $rAck = "cbAck_" . $rBase[1]; - my $rAckAt = "cbAckAt_" . $rBase[1]; - my $rAckBy = "cbAckBy_" . $rBase[1]; - my $rDev = "cbDev_" . $rBase[1]; + keys %{ $hash->{READINGS} }; + while ( my ( $key, $value ) = each %{ $hash->{READINGS} } ) { + if ( $key =~ /^cb_(\d+)$/ ) { + my $rTit = "cbTitle_" . $1; + my $rMsg = "cbMsg_" . $1; + my $rPrio = "cbPrio_" . $1; + my $rAct = "cbAct_" . $1; + my $rAck = "cbAck_" . $1; + my $rAckAt = "cbAckAt_" . $1; + my $rAckBy = "cbAckBy_" . $1; + my $rCancelId = "cbCancelId_" . $1; + my $rDev = "cbDev_" . $1; Log3 $name, 5, "Pushover $name: checking to clean up " . $hash->{NAME} . " $key: time=" - . $rBase[1] . " ack=" + . $1 . " ack=" . ReadingsVal( $name, $rAck, "-" ) . " curTime=" . int( time() ); - if ( ReadingsVal( $name, $rAck, 0 ) == 1 - || $rBase[1] <= int( time() ) ) + if ( ReadingsVal( $name, $rAck, "0" ) eq "1" + || $1 <= int( time() ) ) { delete $hash->{READINGS}{$key}; delete $hash->{READINGS}{$rTit}; @@ -1308,28 +1348,25 @@ sub Pushover_SetMessage2 ($$$$) { delete $hash->{READINGS}{$rAck}; delete $hash->{READINGS}{$rDev}; - if ( defined( $hash->{READINGS}{$rAct} ) ) { - delete $hash->{READINGS}{$rAct}; - } - if ( defined( $hash->{READINGS}{$rAckAt} ) ) { - delete $hash->{READINGS}{$rAckAt}; - } - if ( defined( $hash->{READINGS}{$rAckBy} ) ) { - delete $hash->{READINGS}{$rAckBy}; - } + delete $hash->{READINGS}{$rAct} + if ( defined( $hash->{READINGS}{$rAct} ) ); + delete $hash->{READINGS}{$rAckAt} + if ( defined( $hash->{READINGS}{$rAckAt} ) ); + delete $hash->{READINGS}{$rAckBy} + if ( defined( $hash->{READINGS}{$rAckBy} ) ); + delete $hash->{READINGS}{$rCancelId} + if ( defined( $hash->{READINGS}{$rCancelId} ) ); Log3 $name, 4, - "Pushover $name: cleaned up expired receipt " . $rBase[1]; + "Pushover $name: cleaned up expired receipt " . $1; } } } - Pushover_SendCommand( $hash, "messages.json", $body, %values ) + return Pushover_SendCommand( $hash, "messages.json", $body, %values ) if ( $cmd eq "msg" ); - Pushover_SendCommand( $hash, "glances.json", $body, %values ) + return Pushover_SendCommand( $hash, "glances.json", $body, %values ) if ( $cmd eq "glance" ); - - return; } else { @@ -1340,6 +1377,34 @@ sub Pushover_SetMessage2 ($$$$) { } } +sub Pushover_CancelMessage { + my $hash = shift; + my $cancelId = shift; + my $name = $hash->{NAME}; + my $success = 0; + my $return; + + Log3 $name, 5, "Pushover $name: called function Pushover_CancelMessage()"; + + keys %{ $hash->{READINGS} }; + while ( my ( $key, $value ) = each %{ $hash->{READINGS} } ) { + if ( $key =~ /^cbCancelId_(\d+)$/ + && defined( $value->{VAL} ) + && $value->{VAL} eq $cancelId ) + { + $success = 1; + my $receipt = ReadingsVal( $name, "cb_" . $1, $1 ); + + $return .= " " if ($return); + $return .= + Pushover_SendCommand( $hash, "receipts/$receipt/cancel.json" ); + } + } + + return "Invalid cancel_id '$cancelId'" unless ($success); + return $return; +} + #------------------------------------------------------------------------------ sub Pushover_CGI() { my ($request) = @_; @@ -1398,11 +1463,12 @@ sub Pushover_CGI() { } if ( defined( $revReadings{$receipt} ) ) { - my $rAct = "cbAct_" . $revReadings{$receipt}; - my $rAck = "cbAck_" . $revReadings{$receipt}; - my $rAckAt = "cbAckAt_" . $revReadings{$receipt}; - my $rAckBy = "cbAckBy_" . $revReadings{$receipt}; - my $rDev = "cbDev_" . $revReadings{$receipt}; + my $rAct = "cbAct_" . $revReadings{$receipt}; + my $rAck = "cbAck_" . $revReadings{$receipt}; + my $rAckAt = "cbAckAt_" . $revReadings{$receipt}; + my $rAckBy = "cbAckBy_" . $revReadings{$receipt}; + my $rCancelId = "cbCancelId_" . $revReadings{$receipt}; + my $rDev = "cbDev_" . $revReadings{$receipt}; return ( "text/plain; charset=utf-8", "NOK " . $receipt . ": invalid argument 'acknowledged'" ) @@ -1417,6 +1483,9 @@ sub Pushover_CGI() { if ( ReadingsVal( $name, $rAck, "1" ) eq "0" && $revReadings{$receipt} > int( time() ) ) { + delete $hash->{READINGS}{$rCancelId} + if ( defined( $hash->{READINGS}{$rCancelId} ) ); + readingsBeginUpdate($hash); readingsBulkUpdate( $hash, $rAck, "1" ); @@ -1554,8 +1623,9 @@ sub Pushover_CGI() { action     - type: text - Either a FHEM command to run when user taps link or a supplementary URL to show with your message.
url_title  - type: text - A title for your FHEM command or supplementary URL, otherwise just the URL is shown.
priority   - type: integer - Send as -2 to generate no notification/alert, -1 to always send as a quiet notification, 1 to display as high-priority and bypass the user's quiet hours, or 2 to also require confirmation from the user.
- retry      - type: integer - Mandatory in combination with message priority >= 2.
- expire     - type: integer - Mandatory in combination with message priority >= 2.
+ retry      - type: integer - Mandatory in combination with message priority >= 2.
+ expire     - type: integer - Mandatory in combination with message priority >= 2.
+ cancel_id  - type: text - Custom ID to immediate expire messages with priority >=2 and disable reoccuring notification.
timestamp  - type: integer - A Unix timestamp of your message's date and time to display to the user, rather than the time your message is received by the Pushover servers. Takes precendence over attribute timestamp=1.
sound      - type: text - The name of one of the sounds supported by device clients to override the user's default sound choice.

@@ -1577,6 +1647,20 @@ sub Pushover_CGI() {

+ +
+


+ +
+