LUA commands

From Domoticz
Revision as of 17:24, 3 January 2023 by Walter vl (talk | contribs) (→‎General: added SendNotification)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

Lua tables, commands and variables list for use in Domoticz

This page is created to give an overview of tables, possible commands and variables in Lua that can be used in Domoticz. There is already a lot of information available on the forum, but this is scattered throughout. Next to that, the syntax is not always clear.

See also the LUA scripts section in the eventsystem page for more background info.

Tables available in your scripts

Available in time triggered scripts

timeofday
uservariables
uservariables_lastupdate

globalvariables

otherdevices
otherdevices_idx
otherdevices_lastlevel
otherdevices_lastupdate
otherdevices_svalues

-- Below tables only when such devices exist on your system. (else nil)
otherdevices_barometer
otherdevices_dewpoint
otherdevices_humidity
otherdevices_rain
otherdevices_rain_lasthour
otherdevices_temperature
otherdevices_utility
otherdevices_weather
otherdevices_winddir
otherdevices_windgust
otherdevices_windspeed
otherdevices_zwavealarms

otherdevices_scenesgroups
otherdevices_scenesgroups_idx

Tables available in device triggered scripts

All of the tables available in device triggered scripts

devicechanged
devicechanged_ext

Tables available in variable triggered scripts

All of the tables available in variable triggered scripts

uservariablechanged

General

commandArray = {}
if (devicechanged['MyDeviceName'] == 'On' and otherdevices['MyOtherDeviceName'] == 'Off') then
   commandArray['MyOtherDeviceName1']='On'
   commandArray['MyOtherDeviceName2']='On'
   commandArray['MyOtherDeviceName3']='Off'
   commandArray['MyOtherDeviceName4']='On FOR 10' -- minutes
   commandArray['MyOtherDeviceName5']='Off RANDOM 30' -- random within x minutes
   commandArray['MyOtherDeviceName6']='On REPEAT 5 INTERVAL 5' -- command will be repeated 5 times with 5 seconds interval
   commandArray['MyOtherDeviceName7'] = "On FOR 2 SECONDS REPEAT 9 INTERVAL 4 SECONDS" -- every 4 seconds and do that 9 times, put device On for 2 seconds
   commandArray['MyBlind']='Open'
   commandArray['Scene:MyScene']='On'
   commandArray['Group:MyGroup']='Off AFTER 30' -- seconds
   commandArray[#commandArray + 1] = { SendNotification = 'subject#body#prio#sound#extraData#subSystem1;subSystem2;subSystem3'
   commandArray['OpenURL']='www.yourdomain.com/api/movecamtopreset.cgi' 
   commandArray[#commandArray + 1] = { OpenURL = url .. ' AFTER 0.2' } -- send the url after 0.2 seconds
   commandArray['SendNotification']='subject#body#0#sound#extradata#subsystem' 
          -- Subject is .. the subject
          -- Body is the content of the message
          -- 0 is the priority that you are talking about
          -- sound is the sound you want to use if you use pushover
          -- extradata can be used by some of the notification.
          -- subsystem is one or more of: clickatell;email;fcm;http;kodi;lms;prowl;pushalot;pushbullet;pushover;pushsafer;telegram
   commandArray['SendEmail']='subject#body#to'
   commandArray['TriggerIFTTT']='EventName#Value1#Value2#Value3'
   commandArray['Variable:MyVar']='Some value'
   commandArray[Text:1234]='Some value'
   commandArray['SetSetPoint:MySetPointIdx']='20.5'
   commandArray['SendCamera:1'] = 'SubjectOfMessage AFTER 5' -- This is equal to 'Send camera snapshot with subject "Subject of Message" after 5 seconds. The number (1) in this case is the ID of the camera, not the name!
   commandArray['UpdateDevice']='idx|nValue|sValue' -- for updating Dummy devices e.g. '96|0|Hello World'
end
return commandArray

Round function

local function round(num, dec)
	return ( math.floor( num * 10^dec ) / 10^dec )
end

Update multiple devices in one pass

commandArray = {}
local function update(idx, value1, value2)
    local cmd = string.format("%d|0|%.2f;%.2f", idx, value1, value2)
    table.insert (commandArray, { ['UpdateDevice'] = cmd } )
end

update (16, 320, 0)
update (19, 4, 25)
return commandArray

Update (one or more) numerical devices without using the device idx code

commandArray = {}

local function updatenum(dev, value1)
    local cmd = string.format("%d|0|%d", otherdevices_idx[dev], value1)
    table.insert (commandArray, { ['UpdateDevice'] = cmd } )
end

-- example 1: increment a counter
updatenum('Counter1', tonumber(otherdevices['Counter1']) + 1)

-- example 2: set a fixed value
updatenum('Counter2', 85)

return commandArray

Debugging

Function to dump all variables supplied to the script

function LogVariables(x,depth,name)
    for k,v in pairs(x) do
        if (depth>0) or ((string.find(k,'device')~=nil) or (string.find(k,'variable')~=nil) or 
                         (string.sub(k,1,4)=='time') or (string.sub(k,1,8)=='security')) then
            if type(v)=="string" then print(name.."['"..k.."'] = '"..v.."'") end
            if type(v)=="number" then print(name.."['"..k.."'] = "..v) end
            if type(v)=="boolean" then print(name.."['"..k.."'] = "..tostring(v)) end
            if type(v)=="table" then LogVariables(v,depth+1,k); end
        end
    end
end
-- call with this command
LogVariables(_G,0,'');

Function to dump content of any table

local function tprint (t, indent, done) -- introduced done to prevent infinite loops for tables with self-references
  local done = done or {} 
  indent = indent or 0
  for key, value in pairs (t) do
    pre = (string.rep (" ", indent)) -- indent it
    if type (value) == "table" and not done[value] then
      done [value] = true
      print (pre .. tostring (key) .. ":");
      tprint (value, indent + 2, done)
    elseif type(value) == 'function' and not done[value] then
      print( pre .. (tostring (key) .. "()"))
    else
      pre = pre .. (tostring (key) .. ": ")
      print (pre .. tostring(value))
    end
  end
end


Date and Time

Start script at a specific minute

commandArray = {}
local atMinute = 12

if tonumber(os.date('%M')) ~= atMinute then
    print ('Not the right minute. No further execution.')
    return commandArray
end

Start script at a specific time

local executionTime = '23:21'
local light = 'Flicker' -- Name of your light
commandArray = {}

if os.date('%H:%M') == executionTime then
     for i = 0, 12, 2 do
        commandArray[#commandArray + 1] = { [light] = 'Off AFTER ' .. i }
        commandArray[#commandArray + 1] = { [light] = 'On AFTER ' .. (i + 1) }
    end
end

return commandArray

Function to get timestamp

local function timestamp(dateString, pattern)
    if dateString == nil then return os.time() end
    local pattern = pattern or  "(%d+)%-(%d+)%-(%d+)%s+(%d+):(%d+):(%d+)"
    local year, month, day, hour, minute, seconds = dateString:match(pattern)
    return os.time( { year = year, month = month, day = day, hour = hour, min = minute, sec = seconds } )
end

Function to calculate the time difference (uses timestamp function)

function timedifference(t1, t2) -- both dates with format 'yyyy-mm-dd HH:MM:SS' or nil
  return timestamp(t1) - timestamp(t2)
end

Usage

local mydevice_changed = false
if (mydevice_changed ~= nil and devicechanged['mydevice']) then
    mydevice_changed = true
end

s = otherdevices_lastupdate['mydevice']
if(otherdevices['mydevice']=='On' and timedifference(s) > 600 and not mydevice_changed) then
    commandArray['mydevice']='Off'
end

Note: You should only define and check for mydevice_changed variable when using 'All' scripts.

Time of day

Check if it is daytime or nighttime

Example:

if (timeofday['Daytime']) then ...

or

if (timeofday['Nighttime']) then ...

Devices