Can IFTTT script also work with ID's  [Solved]

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

Moderator: leecollings

Post Reply
pvklink
Posts: 822
Joined: Wednesday 12 November 2014 15:01
Target OS: Raspberry Pi / ODroid
Domoticz version: latest b
Contact:

Can IFTTT script also work with ID's

Post by pvklink »

Hi,

I have a small question about the ifttt script.
It works wunderful within domoticz and IFTTT !

Last part is converting my node-red nora scripts to use ifttvar
I normally use this content to execute a device with ifttvar : [{"obj":"lantaarn","act":"On"}]
But this special node for google home uses id's.

Does this script also handles id's instead of names?
I tried:
[{"obj":"1002","act":"On"}]
[{"obj":1002,"act":"On"}] but they dont work...
am i doing something wrong, or does this script only work with devicename (dont get me wrong, i am VERY happy with this script, i used it 1000 times....

Code: Select all

--[[
syntax of JSON in uservar: 
[
{"obj":"IFvar","set":"TestString"},
{"obj":"IFswitch","act":"On","fS":10,"aS":10,"si":true},
{"obj":"IFSelector","lbl":"Level1"},
{"obj":"IFScene","act":"On"}]

or 
[
{"obj":"IFvar","set":"TestString"},
{"obj":"message from ifttt","msg":["message to all"]},
{"obj":"IFSelector","lbl":"Level1"},
{"obj":"IFScene","act":"On"}
]

max. number of chars = 200
  
every action request in the json should have obj/object and max. one of (act/action, lbl/label, msg/message, set or upd/update, ). 
Other controls (aS/afterSec, fS/ forSec, rAS/repeatAfterSec, si/silent are optional.


if message/msg is the requested action the object field is used as subject and subtable [{}]

            mandatory       line.object    message subject
            mandatory       line.message[1] message body
            optional or nil line.message[2] message priority  (-2=LOW, -1=MODERATE, 0=NORMAL, 1=HIGH, 2=EMERGENCY)
            optional or nil line.message[3] message sound (string like 'pushover','bike','none')
            optional or nil line.message[4] extra 
            optional or nil line.message[5] subsystem or table with subsystems
            
            examples 
            [{"obj":"message from ifttt","msg":["message to all notification systems with default priority"]}]
            [{"obj":"message from ifttt","msg":["message to pushover with high priority",1,null,null,"pushover"]}]
            [{"obj":"message from ifttt","msg":["message to pushover and gcm with low priority",-2,null,null,["pushover","gcm"] ]}]

if OSCommand/os is the requested action, the object field is used program / scriptname. name must be full qualified e.g. "/home/pi/scripts/myScript.sh"

]]--
local iftttvar = "IFTTTvar"  

return 
{
    on =    
    { 
        variables = { iftttvar },   
    },
                    
    logging =
    {   
        level = domoticz.LOG_DEBUG,
        marker = 'ifttt',
   }, 

    execute = function(dz, item)
        
        local function makeLongKeys(str)
            local shortNames = {    
                                    act="action",  -- optional: Can be On, Off or OS/OScommand: 
                                                   -- On; valid for switches and groups and scenes and scenes; Off; valid for switches and groups
                                    aS="afterSec", -- optional: 
                                    fS="forSec",   -- optional: Only valid for standard (On/Off) switches 
                                    lbl="label",   -- optional: levelName or number for selector type switches
                                    msg="message", -- Optional: obj must be set to subject 
                                    obj="object",  -- Mandatory and must be unique in domoticz: name for device, scene, group or uservariable.  
                                    os="OSCommand", -- if os / OSCommand is the requested action, obj must be set to full qualified script /program. 
                                    rAS="repeatAfterSec", -- optional: Only valid for standard (On/Off) switches 
                                    set="set",  -- Optional: update uservariable 
                                    si="silent",  -- Optional: use "si":true in JSON
                                    upd="update", -- Optional: Only valid for devices (set nValue, sValue)
                                    
                               }
 
            for short, long in pairs(shortNames) do
                str = str:gsub('%f[%a]' .. short .. '%f[%A]' ,long) -- this will only replace short with long if short is a whole word
            end
            return str  
        end
        
        local function getBaseType(name)
            for i, tuple in ipairs(_G.domoticzData) do 
                if tuple.name == name then 
                    return tuple.baseType, tuple.id 
                end
            end
        end
        
        local function makeTarget(baseType, name)
            if baseType == 'device' then 
                return dz.devices(name)
            elseif baseType == 'group' then 
                return dz.groups(name)
            elseif baseType == 'scene' then 
                return dz.scenes(name) 
            elseif baseType == 'uservariable' then 
                return dz.variables(name)
            end
        end

        local function doLabelVariant(line, target)
            if line.afterSec and line.silent then 
                target.switchSelector(line.label).silent().afterSec(line.afterSec)
            elseif line.afterSec then
                target.switchSelector(line.label).afterSec(line.afterSec)
           elseif line.silent then
                target.switchSelector(line.label).silent()
           else
                target.switchSelector(line.label)
           end
        end
        
        local function doUpdateVariant(line, target)
            if line.afterSec and line.silent then 
                target.update(line.update).silent().afterSec(line.afterSec)
            elseif line.silent then
                target.update(line.update).silent()
            elseif line.afterSec then
                target.update(line.update).afterSec(line.afterSec)
            else
                target.update(line.update)
            end
        end
        
        local function doSetVariant(line, target)
            if line.afterSec and line.silent then 
                target.set(line.set).silent().afterSec(line.afterSec)
            elseif line.silent then
                target.set(line.set).silent()
            elseif line.afterSec then
                target.set(line.set).afterSec(line.afterSec)
            else
                target.set(line.set)
            end
        end
        
        local function doOnVariant(line, target)
            if line.afterSec and line.forSec and line.silent then 
                target.switchOn().silent().afterSec(line.afterSec).forSec(line.forSec)
            elseif line.afterSec and line.repeatAfterSec and line.silent then 
                target.switchOn().silent().afterSec(line.afterSec).repeatAfterSec(line.repeatAfterSec)
            elseif line.afterSec and line.silent then
                target.switchOn().silent().afterSec(line.afterSec)
           elseif line.afterSec then
                target.switchOn().afterSec(line.afterSec)
           elseif line.silent then
                target.switchOn().silent()
           else
                target.switchOn()
           end
        end
        
        local function doOffVariant(line, target)
            if line.afterSec and line.forSec and line.silent then 
                target.switchOff().silent().afterSec(line.afterSec).forSec(line.forSec)
            elseif line.afterSec and line.repeatAfterSec and line.silent then 
                target.switchOff().silent().afterSec(line.afterSec).repeatAfterSec(line.repeatAfterSec)
            elseif line.afterSec and line.silent then
                target.switchOff().silent().afterSec(line.afterSec)
            elseif line.afterSec then
                target.switchOff().afterSec(line.afterSec)
            elseif line.silent then
                target.switchOff().silent()
            else
                target.switchOff()
            end
        end
        
        local function doStopVariant(line, target)
            if line.afterSec and line.silent then 
                target.stop().silent().afterSec(line.afterSec)
            elseif line.afterSec then
                target.stop().afterSec(line.afterSec)
            elseif line.silent then
                target.stop().silent()
            else
                target.stop()
            end
        end
        
        local function doNotificationVariant(line)
            dz.notify(line.object,line.message[1],line.message[2] or nil,line.message[3] or nil,line.message[4] or nil,line.message[5] or nil)
        end

        local function doOSVariant(osCommand)
            os.execute('sudo ' .. osCommand .. ' &')
            dz.utils.dumpTable(result)
        end

        local function doTasks(result)
            for _, line in ipairs(result) do
                if line.message then
                    doNotificationVariant(line)
                elseif line.action == 'OSCommand' then
                    doOSVariant(line.object)
                else
                    local baseType, idx = getBaseType(line.object)
                    target = makeTarget(baseType, line.object)
                    if not(target) then 
                       dz.log('no device, scene, group or var found',dz.LOG_ERROR)
                       return 
                    end 
                    if line.action and line.action == 'Off' then -- for switch type devices and groups
                        doOffVariant(line, target)
                    elseif line.action and line.action == 'On' then -- for switch type devices, scenes and groups
                        doOnVariant(line, target)
                    elseif line.action and line.action == 'OSCommand' then 
                        doOSVariant(line, target)
                    elseif line.action and line.action == 'Stop' then -- for type blinds 
                        doStopVariant(line, target)
                    elseif line.label then -- for selector type devices
                        doLabelVariant(line, target) 
                    elseif line.set then -- for uservariables
                        doSetVariant(line, target)
                    elseif line.update then -- for devices to set nValu, sValue
                        doUpdateVariant(line, target)
                    end
                end
            end
        end

        -- main 
        local result = dz.utils.fromJSON(makeLongKeys(item.value))
        doTasks(result)
        
    end 
}

Raspberry (raspbian on rpi 3) , Domoticz Beta, dzVents , RFXtrx433e, P1, Hue, Yeelight, Zwave+, X10, ESP(easy), MQTT,Weather Underground, System Alive Checker, Domoticz Remote Server to RPI with Google Assistant,
Jablotron connection, Ikea
User avatar
waaren
Posts: 6028
Joined: Tuesday 03 January 2017 14:18
Target OS: Linux
Domoticz version: Beta
Location: Netherlands
Contact:

Re: Can IFTTT script also work with ID's  [Solved]

Post by waaren »

pvklink wrote: Thursday 17 October 2019 19:52 Does this script also handles id's instead of names?
In it's current form the script cannot deal with numeric objects because it does use the name to search in the getBaseType() function to identify the type of object (device, uservariable, scene, etc..) . A numeric value is not unique in _G.domoticzData.so this cannot be used.

To enable the script to deal with ID's, the JSON in the uservar should include the type of the object. It would then become something like:
[{"obj":1002,"type":"device","act":"On"}] If you are able to send such a JSON into the var, I am happy to code this into your current script.
If you send me the script via PM as you use it now, I will have a look.
Debian buster, bullseye on RPI-4, Intel NUC.
dz Beta, Z-Wave, RFLink, RFXtrx433e, P1, Youless, Hue, Yeelight, Xiaomi, MQTT
==>> dzVents wiki
pvklink
Posts: 822
Joined: Wednesday 12 November 2014 15:01
Target OS: Raspberry Pi / ODroid
Domoticz version: latest b
Contact:

Re: Can IFTTT script also work with ID's

Post by pvklink »

OK, thanks Waaren.
Works perfect now!

Code: Select all

--[[
syntax of JSON in uservar:  
[
{"obj":"IFvar","set":"TestString"},
{"obj":"IFswitch","act":"On","fS":10,"aS":10,"si":true},
{"obj":IFswitchID,"type":"device","act":"On"},   if IFswitchID = numeric , type = device, group, etc mandatory
{"obj":"IFSelector","lbl":"Level1"},
{"obj":"IFScene","act":"On"}]

or 
[
{"obj":"IFvar","set":"TestString"},
{"obj":"message from ifttt","msg":["message to all"]},
{"obj":"IFSelector","lbl":"Level1"},
{"obj":"IFScene","act":"On"}
]

max. number of chars = 200
  
every action request in the json should have obj/object and max. one of (act/action, lbl/label, msg/message, set or upd/update, ). 
Other controls (aS/afterSec, fS/ forSec, rAS/repeatAfterSec, si/silent are optional.


if message/msg is the requested action the object field is used as subject and subtable [{}]

            mandatory       line.object    message subject
            mandatory       line.message[1] message body
            optional or nil line.message[2] message priority  (-2=LOW, -1=MODERATE, 0=NORMAL, 1=HIGH, 2=EMERGENCY)
            optional or nil line.message[3] message sound (string like 'pushover','bike','none')
            optional or nil line.message[4] extra 
            optional or nil line.message[5] subsystem or table with subsystems
            
            examples 
            [{"obj":"message from ifttt","msg":["message to all notification systems with default priority"]}]
            [{"obj":"message from ifttt","msg":["message to pushover with high priority",1,null,null,"pushover"]}]
            [{"obj":"message from ifttt","msg":["message to pushover and gcm with low priority",-2,null,null,["pushover","gcm"] ]}]

if OSCommand/os is the requested action, the object field is used program / scriptname. name must be full qualified e.g. "/home/pi/scripts/myScript.sh"

]]--
local iftttvar = "IFTTTvar"  

return 
{
    on =    
    { 
        variables = { iftttvar },   
    },
                    
    logging =
    {   
        level = domoticz.LOG_DEBUG,
        marker = 'ifttt',
   }, 

    execute = function(dz, item)
        
        local function makeLongKeys(str)
            local shortNames = {    
                                    act="action",  -- optional: Can be On, Off or OS/OScommand: 
                                                   -- On; valid for switches and groups and scenes and scenes; Off; valid for switches and groups
                                    aS="afterSec", -- optional: 
                                    fS="forSec",   -- optional: Only valid for standard (On/Off) switches 
                                    lbl="label",   -- optional: levelName or number for selector type switches
                                    msg="message", -- Optional: obj must be set to subject 
                                    obj="object",  -- Mandatory and must be unique in domoticz: name for device, scene, group or uservariable.  
                                    os="OSCommand", -- if os / OSCommand is the requested action, obj must be set to full qualified script /program. 
                                    rAS="repeatAfterSec", -- optional: Only valid for standard (On/Off) switches 
                                    set="set",  -- Optional: update uservariable 
                                    si="silent",  -- Optional: use "si":true in JSON
                                    upd="update", -- Optional: Only valid for devices (set nValue, sValue)
                                    
                               }
 
            for short, long in pairs(shortNames) do
                str = str:gsub('%f[%a]' .. short .. '%f[%A]' ,long) -- this will only replace short with long if short is a whole word
            end
            return str  
        end
        
        local function getBaseType(line)
            if line.type then return line.type, line.object end
            for i, tuple in ipairs(_G.domoticzData) do 
                if tuple.name == line.object then 
                    return tuple.baseType, tuple.id 
                end
            end
        end
        
        local function makeTarget(baseType, identifier)
            if baseType == 'device' then 
                return dz.devices(identifier)
            elseif baseType == 'group' then 
                return dz.groups(identifier)
            elseif baseType == 'scene' then 
                return dz.scenes(identifier) 
            elseif baseType == 'uservariable' then 
                return dz.variables(identifier)
            end
        end

        local function doLabelVariant(line, target)
            if line.afterSec and line.silent then 
                target.switchSelector(line.label).silent().afterSec(line.afterSec)
            elseif line.afterSec then
                target.switchSelector(line.label).afterSec(line.afterSec)
           elseif line.silent then
                target.switchSelector(line.label).silent()
           else
                target.switchSelector(line.label)
           end
        end
        
        local function doUpdateVariant(line, target)
            if line.afterSec and line.silent then 
                target.update(line.update).silent().afterSec(line.afterSec)
            elseif line.silent then
                target.update(line.update).silent()
            elseif line.afterSec then
                target.update(line.update).afterSec(line.afterSec)
            else
                target.update(line.update)
            end
        end
        
        local function doSetVariant(line, target)
            if line.afterSec and line.silent then 
                target.set(line.set).silent().afterSec(line.afterSec)
            elseif line.silent then
                target.set(line.set).silent()
            elseif line.afterSec then
                target.set(line.set).afterSec(line.afterSec)
            else
                target.set(line.set)
            end
        end
        
        local function doOnVariant(line, target)
            if line.afterSec and line.forSec and line.silent then 
                target.switchOn().silent().afterSec(line.afterSec).forSec(line.forSec)
            elseif line.afterSec and line.repeatAfterSec and line.silent then 
                target.switchOn().silent().afterSec(line.afterSec).repeatAfterSec(line.repeatAfterSec)
            elseif line.afterSec and line.silent then
                target.switchOn().silent().afterSec(line.afterSec)
            elseif line.afterSec and line.forSec then 
                target.switchOn().afterSec(line.afterSec).forSec(line.forSec)
            elseif line.forSec then
                target.switchOn().forSec(line.forSec)
            elseif line.afterSec then
                target.switchOn().afterSec(line.afterSec)

            elseif line.silent then
                target.switchOn().silent()
            else
                target.switchOn()
           end
        end
        
        local function doOffVariant(line, target)
            if line.afterSec and line.forSec and line.silent then 
                target.switchOff().silent().afterSec(line.afterSec).forSec(line.forSec)
            elseif line.afterSec and line.repeatAfterSec and line.silent then 
                target.switchOff().silent().afterSec(line.afterSec).repeatAfterSec(line.repeatAfterSec)
            elseif line.afterSec and line.silent then
                target.switchOff().silent().afterSec(line.afterSec)
            elseif line.afterSec and line.forSec then 
                target.switchOff().afterSec(line.afterSec).forSec(line.forSec)
            elseif line.forSec then
                target.switchOff().forSec(line.forSec)

            elseif line.afterSec then
                target.switchOff().afterSec(line.afterSec)
            elseif line.silent then
                target.switchOff().silent()
            else
                target.switchOff()
            end
        end
        
        local function doStopVariant(line, target)
            if line.afterSec and line.silent then 
                target.stop().silent().afterSec(line.afterSec)
            elseif line.afterSec then
                target.stop().afterSec(line.afterSec)
            elseif line.silent then
                target.stop().silent()
            else
                target.stop()
            end
        end
        
        local function doNotificationVariant(line)
            dz.notify(line.object,line.message[1],line.message[2] or nil,line.message[3] or nil,line.message[4] or nil,line.message[5] or nil)
        end

        local function doOSVariant(osCommand)
            os.execute('sudo ' .. osCommand .. ' &')
            dz.utils.dumpTable(result)
        end

        local function doTasks(result)
            for _, line in ipairs(result) do
                if line.message then
                    doNotificationVariant(line)
                elseif line.action == 'OSCommand' then
                    doOSVariant(line.object)
                else
                    local baseType, idx = getBaseType(line)
                    target = makeTarget(baseType, line.object)
                    if not(target) then 
                       dz.log('no device, scene, group or var found',dz.LOG_ERROR)
                       return 
                    end 
                    if line.action and line.action == 'Off' then -- for switch type devices and groups
                        doOffVariant(line, target)
                    elseif line.action and line.action == 'On' then -- for switch type devices, scenes and groups
                        doOnVariant(line, target)
                    elseif line.action and line.action == 'OSCommand' then 
                        doOSVariant(line, target)
                    elseif line.action and line.action == 'Stop' then -- for type blinds 
                        doStopVariant(line, target)
                    elseif line.label then -- for selector type devices
                        doLabelVariant(line, target) 
                    elseif line.set then -- for uservariables
                        doSetVariant(line, target)
                    elseif line.update then -- for devices to set nValu, sValue
                        doUpdateVariant(line, target)
                    end
                end
            end
        end

        -- main 
        local result = dz.utils.fromJSON(makeLongKeys(item.value))
        doTasks(result)
        
    end 
}
Raspberry (raspbian on rpi 3) , Domoticz Beta, dzVents , RFXtrx433e, P1, Hue, Yeelight, Zwave+, X10, ESP(easy), MQTT,Weather Underground, System Alive Checker, Domoticz Remote Server to RPI with Google Assistant,
Jablotron connection, Ikea
Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest