Lua generic function library

Moderator: leecollings

User avatar
remb0
Posts: 499
Joined: Thursday 11 July 2013 22:21
Target OS: Raspberry Pi / ODroid
Domoticz version: Beta
Location: The Netherlands
Contact:

Lua generic function library

Post 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
Yann
Posts: 12
Joined: Tuesday 17 May 2016 14:42
Target OS: Windows
Domoticz version: 2020.2
Location: France
Contact:

Re: Lua generic function library

Post 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
HP Microserver + Domoticz + Aeon Labs Z-Wave USB +RFX433
SweetPants

Re: Lua generic function library

Post 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
Yann
Posts: 12
Joined: Tuesday 17 May 2016 14:42
Target OS: Windows
Domoticz version: 2020.2
Location: France
Contact:

Re: Lua generic function library

Post by Yann »

Yes, you are right, will try this. Thanks !
HP Microserver + Domoticz + Aeon Labs Z-Wave USB +RFX433
Yann
Posts: 12
Joined: Tuesday 17 May 2016 14:42
Target OS: Windows
Domoticz version: 2020.2
Location: France
Contact:

Re: Lua generic function library

Post by Yann »

Worked perfectly, thank you again !
HP Microserver + Domoticz + Aeon Labs Z-Wave USB +RFX433
User avatar
remb0
Posts: 499
Joined: Thursday 11 July 2013 22:21
Target OS: Raspberry Pi / ODroid
Domoticz version: Beta
Location: The Netherlands
Contact:

Re: Lua generic function library

Post by remb0 »

Yann wrote:Worked perfectly, thank you again !
thanks! feel free to post your creations to help other people.
Yann
Posts: 12
Joined: Tuesday 17 May 2016 14:42
Target OS: Windows
Domoticz version: 2020.2
Location: France
Contact:

Re: Lua generic function library

Post 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 !
HP Microserver + Domoticz + Aeon Labs Z-Wave USB +RFX433
supermat
Posts: 14
Joined: Thursday 07 April 2016 18:57
Target OS: Raspberry Pi / ODroid
Domoticz version:
Contact:

Re: Lua generic function library

Post 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
User avatar
jvdz
Posts: 2189
Joined: Tuesday 30 December 2014 19:25
Target OS: Raspberry Pi / ODroid
Domoticz version: 4.107
Location: Netherlands
Contact:

Re: Lua generic function library

Post by jvdz »

Thought that code looked familiar :-)

Jos
New Garbage collection scripts: https://github.com/jvanderzande/GarbageCalendar
gerard76
Posts: 53
Joined: Wednesday 22 March 2017 9:13
Target OS: Raspberry Pi / ODroid
Domoticz version: 3.8153
Contact:

Re: Lua generic function library

Post 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
User avatar
emme
Posts: 909
Joined: Monday 27 June 2016 11:02
Target OS: Raspberry Pi / ODroid
Domoticz version: latest
Location: Milano, Italy
Contact:

Re: Lua generic function library

Post 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')
The most dangerous phrase in any language is:
"We always done this way"
lvsigo
Posts: 14
Joined: Thursday 24 November 2016 12:14
Target OS: Linux
Domoticz version:
Contact:

Re: Lua generic function library

Post 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
gerard76
Posts: 53
Joined: Wednesday 22 March 2017 9:13
Target OS: Raspberry Pi / ODroid
Domoticz version: 3.8153
Contact:

Re: Lua generic function library

Post 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.
lvsigo
Posts: 14
Joined: Thursday 24 November 2016 12:14
Target OS: Linux
Domoticz version:
Contact:

Re: Lua generic function library

Post 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 ;)
gerard76
Posts: 53
Joined: Wednesday 22 March 2017 9:13
Target OS: Raspberry Pi / ODroid
Domoticz version: 3.8153
Contact:

Re: Lua generic function library

Post 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.
lvsigo
Posts: 14
Joined: Thursday 24 November 2016 12:14
Target OS: Linux
Domoticz version:
Contact:

Re: Lua generic function library

Post 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 ;)
lvsigo
Posts: 14
Joined: Thursday 24 November 2016 12:14
Target OS: Linux
Domoticz version:
Contact:

Re: Lua generic function library

Post 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
Last edited by lvsigo on Saturday 08 April 2017 18:17, edited 1 time in total.
gerard76
Posts: 53
Joined: Wednesday 22 March 2017 9:13
Target OS: Raspberry Pi / ODroid
Domoticz version: 3.8153
Contact:

Re: Lua generic function library

Post 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.
lvsigo
Posts: 14
Joined: Thursday 24 November 2016 12:14
Target OS: Linux
Domoticz version:
Contact:

Re: Lua generic function library

Post 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 ;)
gerard76
Posts: 53
Joined: Wednesday 22 March 2017 9:13
Target OS: Raspberry Pi / ODroid
Domoticz version: 3.8153
Contact:

Re: Lua generic function library

Post by gerard76 »

At least its automatic. But it only works from within a file I presume? Not the lua interface in Domoticz.
Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest