Page 1 of 1

Another approach to handle notification

Posted: Tuesday 14 March 2017 9:00
by emme
Ciao,

I've setted up a different way to handle notification.

I'm not so satisfy by the Telegram (HTTP) notification, of course this is NOT something related to Domoticz itself, but due to the limit of the HTTP api
so, I moved to the telegram CLI Messaging (based on Wiki).
In the meanwhile I'm approaching TTS system and actually I'm using Google TTS API

I have several scripts that sends notification... but going to change everyone, everytime I change/implement/remove something in the notification system is so annoying

So I decided to create a single place where to send notification... using some variables to handle messages and options...
that's my result and I would like to share with you:

SETTING UP VARIABLES
for each notification service you will need 2 variables:

for Google Speech
String gsLastMessage
not really used for data, but just to handle the LastUpdate value that will trigger a kind of 'antispam'

String gsMessage
Message to send

for Telegram-CLI
string tcLastMessage
not really used for data, but just to handle the LastUpdate value that will trigger a kind of 'antispam'

string tcMessage
Message to send
this variable needs to be formatted as follow: FirstName_LastName;Message to send
FirstName_LastName is the destinee name as saved in the contact list (see Telegram-CLI Wiki Page)



string tcSnapShot
Camera ID to send the snapshot to

Any notificatin need should update the Message variable...
then there is a UserVariable event that will handle the messages:

Code: Select all

-- Telegram Client (telegram-cli) script Name
-- https://www.domoticz.com/wiki/Installing_Telegram_Notification_System
local tgEnable   = true  
local tgcCmdLine = 'sudo -u pi telegram.sh '
local tgcLM      = 'tcLastMessage' -- Variable used to limit Messages
local tgcM       = 'tcMessage'
local tgcLMdelay = 3             -- seconds between Messages
                                  -- YES! you can loose some Messages
local tgMessage  = uservariables[tgcM]
local tgSnap     = 'tcSnapShot'   -- Send SnapShot Trigger
local tgSnapSts  = uservariables[tgSnap]
local tgSnapFile = '/home/pi/temp/snapshot.jpg'
local tgcParam   = {}

-- Google Speech Settings & parameters
-- https://github.com/desbma/GoogleSpeech
local gsEnable  = true            -- Enable voice Messages
local gsLM      = 'gsLastMessage' -- Variable used to limit Messages
local gsM       = 'gsMessage' -- Variable used to limit Messages
local gsLMdelay = 10              -- seconds between Messages
                                  -- YES! you can loose some Messages
local gsLang    = 'it'            -- Set Language
local gsDefVol  = '80%'           -- Set RPI Volume
local gsNumID   = '1'             -- numId for volume information
                                  -- use 'amixer controls' to obtain
local gsMessage  = uservariables[gsM]


-- +++++++++++++++++++++++++++++++++
-- ++      TIME DIFFERENCE        ++
-- +++++++++++++++++++++++++++++++++
function timeDiff(dName,dType)
    if dType == 'v' then 
        updTime = uservariables_lastupdate[dName]
    elseif dType == 'd' then
        updTime = otherdevices_lastupdate[dName]
    end 
    t1 = os.time()
    year = string.sub(updTime, 1, 4)
    month = string.sub(updTime, 6, 7)
    day = string.sub(updTime, 9, 10)
    hour = string.sub(updTime, 12, 13)
    minutes = string.sub(updTime, 15, 16)
    seconds = string.sub(updTime, 18, 19)
    
    t2 = os.time{year=year, month=month, day=day, hour=hour, min=minutes, sec=seconds}
    
    tDiff = os.difftime(t1,t2)
    return tDiff
end


-- +++++++++++++++++++++++++++++++++
-- ++TELEGRAM CLIENT NOTIFICATION ++
-- +++++++++++++++++++++++++++++++++
function tgNotify(msgTo, msgText)
    if tgEnable then
        if timeDiff(tgcLM,'v') >= tgcLMdelay then 
            os.execute(tgcCmdLine..'msg '..msgTo..' "'..msgText..'"')
            table.insert (commandArray, {['Variable:'..tgcLM] = 'NO DATA' })
        end
-- Send Snapshot
        if tgSnapSts ~= '0' then 
            os.execute ('wget "http://127.0.0.1:8080/camsnapshot.jpg?idx="'..tgSnapSts..' -O '..tgSnapFile)
            os.execute(tgcCmdLine..'post_photo '..msgTo..' '..tgSnapFile)
            table.insert (commandArray, {['Variable:'..tgSnap] = '0' })
        end 
    end     
end 

-- +++++++++++++++++++++++++++++++++
-- ++       GOOGLE SPEECH API     ++
-- +++++++++++++++++++++++++++++++++
function gSpeech(msgText, volSet, langSet)
    if gsEnable then 
        if volSet == nil then
            volSet = gsDefVol
        end 

        if langSet == nil then
            langSet = gsLang
        end

        if timeDiff(gsLM,'v') >= gsLMdelay then 
            os.execute('amixer cset numid='..gsNumID..' '..volSet..' && google_speech -l '..langSet..' '..msgText)
            table.insert (commandArray, {['Variable:'..gsLM] = 'NO DATA' })
        end 
    end 
end      


commandArray = {}

    if uservariablechanged[tgcM] then 
    -- Parsing Telegram Message String 
        for w in (tgMessage..';'):gmatch('([^;]*);') do table.insert(tgcParam, w) end
        if tgcParam[1] ~= 'NO DATA' then 
            tgNotify(tgcParam[1], tgcParam[2])
            table.insert (commandArray, {['Variable:'..tgcM] = 'NO DATA;NO DATA'})
        end 
    end 

    if uservariablechanged[gsM] then 
        if gsMessage ~= 'NO DATA' then 
            gSpeech(gsMessage, gsDefVol, gsLang)
            table.insert (commandArray, {['Variable:'..gsM] = 'NO DATA'})
        end 
    end 

return commandArray
Some notes:
to prevent spamming messages I've introduced a Delay variable that (in secs) define the period between messages
This parameter cannot be get from the Message variable.
In this way... yes.. unfortunately you can loose some notification (in case they are fired together)

The Telegram script has been configured running user pi while Domoticz runs as root, so tu use the configuration stored in ~/.telegram-cli I have foced to run as pi with sudo -i pi

Why variables?
because I do not need to have a log
How to Force Messages?
edit the Message Variable manually
What is 'NO DATA'?
It means the script has run and the variables have been resetted
I see the message in the variable, but no notification has been sent
I know.. I think there are several updates of the variable within the delay period...
the message stay there also as information about 'what was not sent'


USAGE
to be used in your other script simply update the message variable (and camera IDX for telegram snapshot)

like:

Code: Select all

commandArray['Variable:tcMessage'] = 'Test Message for Telegram... snapshot will follow'
commandArray['Variable:tcSnapSta'] = '2'  -- Send camera 2 Snapshot
commandArray['Variable:gsMessage'] = 'Test Message for Google Speech'
here it is...
well.. don't yell to me please :oops: :oops:
ciao
M

Re: Another approach to handle notification

Posted: Tuesday 14 March 2017 9:07
by Egregius
What's wrong with the telegram api?

Re: Another approach to handle notification

Posted: Tuesday 14 March 2017 9:33
by emme
I'm still using HTTP support for device notifications using Telegram API,
but at a code level I do prefer a single place where notify
API works for simple text messages... if I want to send a snapshot of a camera I do need other option that actuall API does not provide

:P
ciao
M

Re: Another approach to handle notification

Posted: Tuesday 14 March 2017 11:12
by Egregius
As far as I know and use the api you can sent text, pictures and movies.