Lua generic function library

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

Lua generic function library

Post by remb0 » Wednesday 19 August 2015 10:22

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

Re: Lua generic function library

Post by Yann » Tuesday 17 May 2016 19:15

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
Posts: 1587
Joined: Friday 12 July 2013 21:24
Target OS: Linux
Domoticz version: V3.8742
Location: The Netherlands
Contact:

Re: Lua generic function library

Post by SweetPants » Tuesday 17 May 2016 20:59

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

Re: Lua generic function library

Post by Yann » Thursday 19 May 2016 15:27

Yes, you are right, will try this. Thanks !
HP Microserver + Domoticz + Aeon Labs Z-Wave USB +RFX433

Yann
Posts: 7
Joined: Tuesday 17 May 2016 14:42
Target OS: Windows
Domoticz version: 3.5143
Location: France
Contact:

Re: Lua generic function library

Post by Yann » Saturday 28 May 2016 14:22

Worked perfectly, thank you again !
HP Microserver + Domoticz + Aeon Labs Z-Wave USB +RFX433

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

Re: Lua generic function library

Post by remb0 » Saturday 28 May 2016 19:42

Yann wrote:Worked perfectly, thank you again !
thanks! feel free to post your creations to help other people.

Yann
Posts: 7
Joined: Tuesday 17 May 2016 14:42
Target OS: Windows
Domoticz version: 3.5143
Location: France
Contact:

Re: Lua generic function library

Post by Yann » Wednesday 01 June 2016 12:31

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: 13
Joined: Thursday 07 April 2016 18:57
Target OS: Raspberry Pi
Domoticz version:
Contact:

Re: Lua generic function library

Post by supermat » Tuesday 07 March 2017 14:23

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: 1022
Joined: Tuesday 30 December 2014 20:25
Target OS: Raspberry Pi
Domoticz version: Stable
Location: Netherlands
Contact:

Re: Lua generic function library

Post by jvdz » Tuesday 07 March 2017 17:12

Thought that code looked familiar :-)

Jos

gerard76
Posts: 64
Joined: Wednesday 22 March 2017 10:13
Target OS: Raspberry Pi
Domoticz version: 3.8153
Contact:

Re: Lua generic function library

Post by gerard76 » Friday 31 March 2017 19:12

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: 626
Joined: Monday 27 June 2016 11:02
Target OS: Raspberry Pi
Domoticz version: latest
Location: Milano, Italy
Contact:

Re: Lua generic function library

Post by emme » Monday 03 April 2017 9:40

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')
That's one small step for a programmer, one giant leap for me!
- - - - -
Raspberry Pi3 + AeonStick G5 + RFXCOMM433 + iRTrans Server + NodeJS
There's no stress in the mess!!

lvsigo
Posts: 17
Joined: Thursday 24 November 2016 13:14
Target OS: Linux
Domoticz version:
Contact:

Re: Lua generic function library

Post by lvsigo » Wednesday 05 April 2017 23:42

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: 64
Joined: Wednesday 22 March 2017 10:13
Target OS: Raspberry Pi
Domoticz version: 3.8153
Contact:

Re: Lua generic function library

Post by gerard76 » Friday 07 April 2017 13:32

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: 17
Joined: Thursday 24 November 2016 13:14
Target OS: Linux
Domoticz version:
Contact:

Re: Lua generic function library

Post by lvsigo » Friday 07 April 2017 22:49

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: 64
Joined: Wednesday 22 March 2017 10:13
Target OS: Raspberry Pi
Domoticz version: 3.8153
Contact:

Re: Lua generic function library

Post by gerard76 » Saturday 08 April 2017 6:42

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: 17
Joined: Thursday 24 November 2016 13:14
Target OS: Linux
Domoticz version:
Contact:

Re: Lua generic function library

Post by lvsigo » Saturday 08 April 2017 8:56

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: 17
Joined: Thursday 24 November 2016 13:14
Target OS: Linux
Domoticz version:
Contact:

Re: Lua generic function library

Post by lvsigo » Saturday 08 April 2017 11:44

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: 64
Joined: Wednesday 22 March 2017 10:13
Target OS: Raspberry Pi
Domoticz version: 3.8153
Contact:

Re: Lua generic function library

Post by gerard76 » Saturday 08 April 2017 13:06

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: 17
Joined: Thursday 24 November 2016 13:14
Target OS: Linux
Domoticz version:
Contact:

Re: Lua generic function library

Post by lvsigo » Saturday 08 April 2017 17:40

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: 64
Joined: Wednesday 22 March 2017 10:13
Target OS: Raspberry Pi
Domoticz version: 3.8153
Contact:

Re: Lua generic function library

Post by gerard76 » Saturday 08 April 2017 23:09

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: BakSeeDaa, Dropshot and 2 guests