universal notification function, with parametric reminder time?

Easy to use, 100% Lua-based event scripting framework.

Moderator: leecollings

Post Reply
renerene
Posts: 356
Joined: Wednesday 03 August 2016 11:36
Target OS: -
Domoticz version:
Contact:

universal notification function, with parametric reminder time?

Post by renerene »

"The battery is low, replace it" (once per day)
"the door is open and it's freezing outside" (every 5 minutes)


These are two typical messages that can be sent as log, notification or spoken on Alexa/Google/Jarvis@home.
Mostly it is triggered by a script, multiple time each hour. Because I don't want notification bombs there is some sort of 'once per day' variable, that is resetted once per day.

This can be done more efficient.

Recently I found out the universal helper scripts in dzVents. I am thinking about writing an universal routine, with following parameters:
function report (message, log, speak, notify, muteTimeMin)

Question
How to program the muteTimeMin part? Ideas welcome.

So, for instance,

Code: Select all

if previousMessage.minutesAgo > muteTimeMin then 
     notitfy message 
     reset muteTime
else
     keep Quiet and wait some more
end

Offcourse, there will be more messages going on at the same time and domoticz need to keep track of the time when each message was notified.
User avatar
waaren
Posts: 6028
Joined: Tuesday 03 January 2017 14:18
Target OS: Linux
Domoticz version: Beta
Location: Netherlands
Contact:

Re: universal notification function, with parametric reminder time?

Post by waaren »

renerene wrote: Monday 14 January 2019 20:04 "The battery is low, replace it" (once per day)
"the door is open and it's freezing outside" (every 5 minutes)

These are two typical messages that can be sent as log, notification or spoken on Alexa/Google/Jarvis@home.
Mostly it is triggered by a script, multiple time each hour. Because I don't want notification bombs there is some sort of 'once per day' variable, that is resetted once per day.
function report (message, log, speak, notify, muteTimeMin)
Question
How to program the muteTimeMin part? Ideas welcome.

Offcourse, there will be more messages going on at the same time and domoticz need to keep track of the time when each message was notified.
Nice idea !

What about this ?

Code: Select all

-- global_data.lua 
 
return {
    
        data = {
                       managedNotifications                    = { initial = {}},
                  },

	helpers =   {
                    managedNotify = function (dz, message, messageType, muteTimeMin,quietHours) 
                        local now = os.time(os.date('*t'))                  -- seconds since 1/1/1970 00:00:01
                        muteTimeMin = muteTimeMin or 1
                        
                        if ( not dz.globalData.managedNotifications[message] ) or 
                           (( dz.globalData.managedNotifications[message] + muteTimeMin * 60 ) <= now ) then
                                if quietHours and dz.time.matchesRule("at " .. quietHours) then
                                    dz.log("Quiet hours: no notification.") .. 
                                else
                                    dz.notify("managedNotification", message,nil,nil,nil,messageType)  
                                    dz.globalData.managedNotifications[message] = now
                                end     
                        else
                            -- No action required yet.  
                            dz.log("Last '" .. message .. "' message was send at " .. 
                                    os.date("%A, %d %B %Y (%H:%M)",dz.globalData.managedNotifications[message]) ,dz.LOG_FORCE)
                       end
                    end,
                },
       }

Code: Select all

-- managedNotify test script

return {
   on = { timer = { "every minute" }},    
   
   execute = function(dz)
   
       -- 1st parm (dz)        required 
       -- 2nd parm (message)   required
       -- 3rd parm (notification subsystem) optional but required if any of the next parms in use (when nil defaults to all)
       -- 4th parm (frequency in minutes) optional and defaults to 1 but required when using 5th parm.
       -- 5th parm (quiet hours) optional        
   
       dz.helpers.managedNotify(dz, "first message",  dz.NSS_PUSHOVER, 4)        
       dz.helpers.managedNotify(dz, "Next message",  dz.NSS_TELEGRAM, 3)        
       dz.helpers.managedNotify(dz, "Third message",  dz.NSS_GOOGLE_CLOUD_MESSAGING, 7,"10:59-11:15")     -- last parm optional
       dz.helpers.managedNotify(dz, "4th message",  dz.NSS_TELEGRAM, 1 ,"21:00-11:36")        
       dz.helpers.managedNotify(dz, "5th message")        
       dz.helpers.managedNotify(dz, "6th message",nil,15)        
   end
}

Last edited by waaren on Tuesday 15 January 2019 11:43, edited 1 time in total.
Debian buster, bullseye on RPI-4, Intel NUC.
dz Beta, Z-Wave, RFLink, RFXtrx433e, P1, Youless, Hue, Yeelight, Xiaomi, MQTT
==>> dzVents wiki
renerene
Posts: 356
Joined: Wednesday 03 August 2016 11:36
Target OS: -
Domoticz version:
Contact:

Re: universal notification function, with parametric reminder time?

Post by renerene »

This. Is. Awesome
thank you/respect!
freijn
Posts: 536
Joined: Friday 23 December 2016 16:40
Target OS: Raspberry Pi / ODroid
Domoticz version: Stable
Location: Netherlands Purmerend
Contact:

Re: universal notification function, with parametric reminder time?

Post by freijn »

Very interesting, but please help me understand.

Where do I put the -- global_data.lua script so the -- managedNotify test script can find the function ?
elmortero
Posts: 248
Joined: Sunday 29 November 2015 20:46
Target OS: Raspberry Pi / ODroid
Domoticz version: 3.9639
Location: Spain
Contact:

Re: universal notification function, with parametric reminder time?

Post by elmortero »

User avatar
waaren
Posts: 6028
Joined: Tuesday 03 January 2017 14:18
Target OS: Linux
Domoticz version: Beta
Location: Netherlands
Contact:

Re: universal notification function, with parametric reminder time?

Post by waaren »

freijn wrote: Tuesday 15 January 2019 8:55 Very interesting, but please help me understand.

Where do I put the -- global_data.lua script so the -- managedNotify test script can find the function ?
in the script directory.

Note: there can be only one global_data.lua on your system. Either in /path/to/domoticz/scripts/dzVents/script or in Domoticz' internal GUI web editor.
Debian buster, bullseye on RPI-4, Intel NUC.
dz Beta, Z-Wave, RFLink, RFXtrx433e, P1, Youless, Hue, Yeelight, Xiaomi, MQTT
==>> dzVents wiki
User avatar
waaren
Posts: 6028
Joined: Tuesday 03 January 2017 14:18
Target OS: Linux
Domoticz version: Beta
Location: Netherlands
Contact:

Re: universal notification function, with parametric reminder time?

Post by waaren »

Edited my example (see post #2) to include optional quiet hours.
Debian buster, bullseye on RPI-4, Intel NUC.
dz Beta, Z-Wave, RFLink, RFXtrx433e, P1, Youless, Hue, Yeelight, Xiaomi, MQTT
==>> dzVents wiki
renerene
Posts: 356
Joined: Wednesday 03 August 2016 11:36
Target OS: -
Domoticz version:
Contact:

Re: universal notification function, with parametric reminder time?

Post by renerene »

Can a purge function be added?

I use this routine now my main notification tool. Often there is a variable in the text ("temperature is..") which makes the index of the managedNotifications table unique, making the mute function not work for the same message type with another variable value. This is not a big issue. But I don't like the idea of the table building up with values that will be never looked after again.

Therefore: do a once per week purge of messages older than 30 days?
User avatar
waaren
Posts: 6028
Joined: Tuesday 03 January 2017 14:18
Target OS: Linux
Domoticz version: Beta
Location: Netherlands
Contact:

Re: universal notification function, with parametric reminder time?

Post by waaren »

renerene wrote: Saturday 26 January 2019 23:02 Can a purge function be added?
sure. It is already possible to do that by removing the data file. It will be recreated using the initial values, the next time the global_data script executes.
I use this routine now my main notification tool. Often there is a variable in the text ("temperature is..") which makes the index of the managedNotifications table unique, making the mute function not work for the same message type with another variable value. This is not a big issue. But I don't like the idea of the table building up with values that will be never looked after again.
Therefore: do a once per week purge of messages older than 30 days?
In below script, I added subject as a parameter. This does mean that your scripts calling this helper function need to be modified to insert the subject as 2nd parameter. :!: :!:

Extra's:
  • using the subject "delete" will cause the managedNotify table entry with the index "message" to be removed
  • using the subject "deleteAll"will cause all managedNotify table entries to be removed.
  • managedNotify table entries for a message, created 30 days ago or earlier, will be removed when any new message will be added to this table

Code: Select all

-- global_data.lua 
 
return {
        data =  {
                    managedNotifications                    = { initial = {}},
                },
	helpers =   {
                    managedNotify = function (dz, subject,message, messageType, muteTimeMin,quietHours) 
                        local now = os.time(os.date('*t'))                  -- seconds since 1/1/1970 00:00:01
                        muteTimeMin = muteTimeMin or 1
                        if subject == nil or string.lower(subject) == "delete"  then 
                            dz.globalData.managedNotifications[message] = nil 
                            dz.log("message " .. message .. "  on request deleted",dz.LOG_FORCE)
                            return 3
                        elseif string.lower(subject) ==  "deleteall" then
                            dz.globalData.managedNotifications = nil 
                            dz.log("All messages on request deleted",dz.LOG_FORCE)
                            return 4
                        elseif ( not dz.globalData.managedNotifications[message] ) or 
                              (( dz.globalData.managedNotifications[message] + muteTimeMin * 60 ) <= now ) then
                                if quietHours and dz.time.matchesRule("at " .. quietHours) then
                                    dz.log("Quiet hours: no notification.")
                                    return 1
                                else
                                    dz.notify(subject, message,nil,nil,nil,messageType)  
                                    dz.globalData.managedNotifications[message] = now
                                    local cleanupPeriod = 30 * 24 * 3600                                -- 30 days
                                    for key,timeStamp in pairs(dz.globalData.managedNotifications) do
                                        if ( dz.globalData.managedNotifications[key] + cleanupPeriod ) < now then 
                                            dz.globalData.managedNotifications[key] = nil
                                            dz.log("(Old) message " .. key .. "  deleted",dz.LOG_FORCE)
                                        end
                                    end
                                    return 0
                                end     
                        else
                            -- No action required yet.  
                            dz.log("Last '" .. message .. "' message was send at " .. 
                                    os.date("%A, %d %B %Y (%H:%M)",dz.globalData.managedNotifications[message]) ,dz.LOG_FORCE)
                            return 2        
                        end
                    end,
                },
        }

Code: Select all

-- managedNotify test script

return {
   on = { timer = { "every minute" }},    
   
   execute = function(dz)
   
       -- 1st parm (dz)        required 
       -- 2nd parm (subject)   if nil or "deleted" then table entry for message will be removed
       --                      if "deleteAll" then all table entries will be removed
       --                      else required => notification subject 
       -- 3rd parm (message)   required except when subject is "deleteAll"
       -- 4th parm (notification subsystem) optional but required if any of the next parms in use (when nil defaults to all)
       -- 5th parm (frequency in minutes) optional and defaults to 1 but required when using 6th parm.
       -- 6th parm (quiet hours) optional        
   
      -- dz.helpers.managedNotify(dz, "testMessage_1", "first message",  dz.NSS_PUSHOVER,               4)        
      -- dz.helpers.managedNotify(dz, "testMessage_2", "Next message",   dz.NSS_TELEGRAM,               3)        
      -- dz.helpers.managedNotify(dz, "testMessage_3", "Third message",  dz.NSS_GOOGLE_CLOUD_MESSAGING, 7, "10:59-11:15")
      -- dz.helpers.managedNotify(dz, "testMessage_4", "4th message",    dz.NSS_TELEGRAM,               1, "22:00-11:36")        
      -- dz.helpers.managedNotify(dz, "testMessage_5", "5th message",    dz.NSS_TELEGRAM,             120 )        
      -- dz.helpers.managedNotify(dz, "testMessage_6", "6th message",    nil,                          15 )        
      
      -- dz.helpers.managedNotify(dz, "delete","6th message") -- the will remove table entry with key 
      -- dz.helpers.managedNotify(dz, "deleteAll") -- the will remove all notifications in table 
   end 
}
Debian buster, bullseye on RPI-4, Intel NUC.
dz Beta, Z-Wave, RFLink, RFXtrx433e, P1, Youless, Hue, Yeelight, Xiaomi, MQTT
==>> dzVents wiki
Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest