Page 1 of 2

Lua generic function library

Posted: Wednesday 19 August 2015 10:22
by remb0
With a friend we made some nice lua scripts.. but when you made some scripts you always need the same coding for: rounding, calculate time differences etc.
So we made the following file: MyFunc.lua
Spoiler: show

Code: Select all

local My ={}

	function My.GetUserVar(UserVar)
		Waarde=uservariables[UserVar]
		if Waarde==nil then
			print(".  User variable not set for : " .. UserVar)
			UserVarErr=UserVarErr+1
		end
		return Waarde
	end

	function My.File_exists(file)
	  local f = io.open(file, "rb")
	  if f then f:close() end
	  return f ~= nil
	end

	function My.Round(num, idp)
	   local mult = 10^(idp or 0)
	   return math.floor(num * mult + 0.5) / mult
	end

	function My.GetValue(Text, GetNr)
		Part=1
		for match in (Text..';'):gmatch("(.-)"..';') do
		   if Part==GetNr then MyValue = tonumber(match) end
		   Part=Part+1
		end
		return MyValue
	end
	
	-- replace the last character
	function My.EnumClear(Text)
		a=string.len(Text)
		b=string.sub(Text,a,a)
		if b=="," or b==" " then Text=string.sub(Text,1,a-1) end
		a=string.len(Text)
		b=string.sub(Text,a,a)
		if b=="," or b==" " then Text=string.sub(Text,1,a-1) end
		return Text
	end

	function My.ConvTime(TimeX)
		year = string.sub(TimeX, 1, 4)
		month = string.sub(TimeX, 6, 7)
		day = string.sub(TimeX, 9, 10)
		hour = string.sub(TimeX, 12, 13)
		minutes = string.sub(TimeX, 15, 16)
		seconds = string.sub(TimeX, 18, 19)
		ResTime = os.time{year=year, month=month, day=day, hour=hour, min=minutes, sec=seconds}
		return ResTime
	end

	function My.TimeDiff(Time1,Time2)
		if string.len(Time1)>12 then Time1 = My.ConvTime(Time1) end
		if string.len(Time2)>12 then Time2 = My.ConvTime(Time2) end	
		ResTime=os.difftime (Time1,Time2)
		return ResTime
	end
return My
You can use the functions in every lua script after you include the library with this lines:

Code: Select all

package.path = package.path .. ';' .. '/home/pi/domoticz/scripts/lua/?.lua'
My = require('MyFunc')
Example uasage

Check if file exist.

Code: Select all

	if not My.File_exists(LogFile) then
Get UserVar and Print when missing
Get value of a user variable, but when the user variable not exist the function prints print (". User variable not set for : " .. UserVar) to the log.
When you use this function for all the variables users who copy your script gets in logging a message which variables they must make.

Code: Select all

LogFile        = My.GetUserVar("SUN_LogFile")
Get the X value of a device
5 in this example can you change in the number of the value.
my Wind meter gives: 207.00;SSW;9;18;16.4;16.4 so I need fift value for temperature

Code: Select all

Variable      = My.GetValue(otherdevices_svalues[DeviceName],5)	


Round numbers.

Code: Select all

My.Round(ValueThatNeedsToRounded,1)
TimeDifferences
The example below gave to difference between now and the time that a devices is last changed in minutes

Code: Select all

TDiff = My.Round(My.TimeDiff(os.time(),otherdevices_lastupdate[DeviceManual])/60,0)


If you Have also some nice functions, reply with coding, explanation and example

Re: Lua generic function library

Posted: Tuesday 17 May 2016 19:15
by Yann
Worked great before but now, with the new Domoticz versions, Lua scripts are stored in the Domoticz database .... what is the package path now ?
Thanks

Re: Lua generic function library

Posted: Tuesday 17 May 2016 20:59
by SweetPants
Yann wrote:Lua scripts are stored in the Domoticz database
Only if you use the build in editor. You can still use the 'old' way for LUA scripts

Re: Lua generic function library

Posted: Thursday 19 May 2016 15:27
by Yann
Yes, you are right, will try this. Thanks !

Re: Lua generic function library

Posted: Saturday 28 May 2016 14:22
by Yann
Worked perfectly, thank you again !

Re: Lua generic function library

Posted: Saturday 28 May 2016 19:42
by remb0
Yann wrote:Worked perfectly, thank you again !
thanks! feel free to post your creations to help other people.

Re: Lua generic function library

Posted: Wednesday 01 June 2016 12:31
by Yann
Good point ! Let's do it
I wanted to create a library to send pushbullet messages to specific users. In Domoticz, the notifications settings allow only 1 pushbullet user, but I wanted to send messages either to my wife or myself. In other cases, I wanted to send a message only on Pushbullet (vs all notifications SMS/Email ...).
Hence this function
First you need to install curl in C:\programs\Curl (or other directory but then you have to change the command line bellow)

SEND MESSAGE TO PUSHBULLET
Message should be in this format 'title;message' ... so avoid ';' in your title :D
If you need to insert space in the text, use %20 instead otherwise the command line won't work

Code: Select all

local Lib={};

  function Lib.Pushbullet(Message)
    local pb_token = 'yourpushbullettoken'
    local pb_total = Message
    local val=string.find(pb_total,";")
    local pb_title = string.sub(pb_total,1,val-1)
    local pb_body = string.sub(pb_total,val+1)


    local pb_command = 'c:\\Programs\\Curl\\curl -u ' .. pb_token .. ': "https://api.pushbullet.com/v2/pushes" -d type=note -d title="' .. pb_title .. '" -d body="' .. pb_body ..'"'
  
    -- Run curl command
    exec_success = os.execute(pb_command)

  end

return Lib
Then you can use it anywhere like this

Code: Select all

Lib.Pushbullet('essai;text')
Hope it will help someone !

Re: Lua generic function library

Posted: Tuesday 07 March 2017 13:23
by supermat
Hi, it is not my creation, but I use it so much. I prefer use an idx rather than a name of a sensor. So I can rename the sensor an the script continues to work.

So I need to convert an idx to a name with this fonction

The code is from here : https://www.domoticz.com/forum/viewtopic.php?t=11330

Code: Select all

function getdevname4idx(deviceIDX)
 for i, v in pairs(otherdevices_idx) do
   if v == deviceIDX then
     return i
   end
 end
 return 0
end

Re: Lua generic function library

Posted: Tuesday 07 March 2017 16:12
by jvdz
Thought that code looked familiar :-)

Jos

Re: Lua generic function library

Posted: Friday 31 March 2017 19:12
by gerard76

Code: Select all

function My.ConvTime(TimeX)
  year = string.sub(TimeX, 1, 4)
  month = string.sub(TimeX, 6, 7)
  day = string.sub(TimeX, 9, 10)
  hour = string.sub(TimeX, 12, 13)
  minutes = string.sub(TimeX, 15, 16)
  seconds = string.sub(TimeX, 18, 19)
  ResTime = os.time{year=year, month=month, day=day, hour=hour, min=minutes, sec=seconds}
  return ResTime
end
Could be written as:

Code: Select all

function My.ConvTime(timestamp)
   y, m, d, H, M, S = timestamp:match("(%d+)-(%d+)-(%d+) (%d+):(%d+):(%d+)")
   return os.time{year=y, month=m, day=d, hour=H, min=M, sec=S}
end

Re: Lua generic function library

Posted: Monday 03 April 2017 9:40
by emme
my most used functions:

Changed TimeDiff to get deice and variable time using one procedure

Code: Select all

-- +++++++++++++++++++++++++++++++++
-- ++      TIME DIFFERENCE        ++
-- +++++++++++++++++++++++++++++++++
-- Return seconds of last update date for a Variable or a Device 
    function Utils.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
usage: timeDiff(name,'v|d')

Convert a character separated fixed prefix string into a table

Code: Select all

-- +++++++++++++++++++++++++++++++++
-- ++         string2table        ++
-- +++++++++++++++++++++++++++++++++
-- Return a table from a char separated string for a prefixed pattern
    function Utils.str2tab(Text, sepVal, prfVal)
        tblVals = {}
        for varName, varVal in pairs(uservariables) do 
            if (string.sub(varName,1,string.len(prfVal)) == prfVal) then 
                for tmpVal in (varName..sepVal):gmatch('([^'..sepVal..']*)'..sepVal) do table.insert(tblVals, tmpVal) end 
            end 
        end 
        return tblVals 
    end 
usage
myTbl = {}
myTbl = Utils.str2tab(myString, ';','Light')

Re: Lua generic function library

Posted: Wednesday 05 April 2017 23:42
by lvsigo
Hi,

No need to add new package.path
Juste use dofile()


found this on french forum
https://github.com/vil1driver/lua/blob/ ... odules.lua

Re: Lua generic function library

Posted: Friday 07 April 2017 13:32
by gerard76
using require() has benefits over dofile(). Require checks if a file is already included and does not include it again.

The standard package.path in domoticz contains the working dir. For me this is /home/pi/domoticz so I can use require('scripts/lua/group') to include my group library for example. No need to fiddle with the package path.

Re: Lua generic function library

Posted: Friday 07 April 2017 22:49
by lvsigo
nice to know, but sorry it doesn't work (v3.7149)

print(package.path)
/usr/local/share/lua/5.2/?.lua;
/usr/local/share/lua/5.2/?/init.lua;
/usr/local/lib/lua/5.2/?.lua;
/usr/local/lib/lua/5.2/?/init.lua;
./?.lua
then only use require() result as an error

and how the file could be already included ?
I need to include it in all scripts..
dofile() do the job ;)

Re: Lua generic function library

Posted: Saturday 08 April 2017 6:42
by gerard76
It works, you just have to use it correctly ;)

I do not know what your working directory is. You can find out with

Code: Select all

print(io.popen("pwd"):read'*l')
then require() will work fine if you specify the correct path.

Files can be double included if any of the files you include also include other files. Any of my libraries that need to talk to the Domoticz API will include the JSON lib for example. Using require() prevents it from being included multiple times.

dofile() also works, just as (loadfile "<file path>")() the "preferred" way would be require() though.

Re: Lua generic function library

Posted: Saturday 08 April 2017 8:56
by lvsigo

Code: Select all

print(io.popen("pwd"):read'*l')
return

Code: Select all

/
if I try to include modules.lua like this

Code: Select all

require('home/lvsigo/domoticz/scripts/lua/modules')
it works
thanks ;)

Re: Lua generic function library

Posted: Saturday 08 April 2017 11:44
by lvsigo
Can domoticz pass to lua scripts, the lua path ?
for replacing this ?

Code: Select all

luaDir = '/home/username/domoticz/scripts/lua/'					-- linux
--luaDir = 'C:\\Program Files (x86)\\Domoticz\\scripts\\lua\\'			-- windows
--luaDir = '/volume1/@appstore/domoticz/var/scripts/lua/'			-- synology

Re: Lua generic function library

Posted: Saturday 08 April 2017 13:06
by gerard76
Normally you can determine this from the script with debug.getinfo(1).source, but because the scripts are stored in the database this is not possible. At least, not to my knowledge.

Re: Lua generic function library

Posted: Saturday 08 April 2017 17:40
by lvsigo
thanks,

this seems to works for linux or windows system

Code: Select all

if package.config:sub(1,1) == '/' then
	luaDir = debug.getinfo(1).source:match("@?(.*/)")
else
	luaDir = string.gsub(debug.getinfo(1).source:match("@?(.*\\)"),'\\','\\\\')
end
print(luaDir)
maybe not optimal ;)

Re: Lua generic function library

Posted: Saturday 08 April 2017 23:09
by gerard76
At least its automatic. But it only works from within a file I presume? Not the lua interface in Domoticz.