Page 4 of 17

Re: Introducing dzVents - Domoticz Lua file based event scripting made e-z!

Posted: Sunday 13 March 2016 16:37
by dannybloe
dakipro wrote:Thanks about the LUX, it works as raw data. How to access temperature, also like raw?
I tried briefly and didn't find it, althought I do not need it at the moment

Here is the latest "night lights" version, might be useful for someone as a start script

Code: Select all

return {
	active = true,                  -- set to true to activate this script
	on = {
		39,                         	-- index of the device - 39 book PIR
		['timer'] = 'every 2 minutes',  -- minutes: xx:00, xx:02, xx:04, ..., xx:58
		
	},

	execute = function(domoticz, motionSensor) 
		--initialize variables
		if (motionSensor==nil) then
		   -- timer was triggered, get my switch
		   motionSensor = domoticz.devices[39] --book PIR
		end
		luxLightValue = domoticz.devices[40].rawData[1] 
		tvLED = domoticz.devices[35]
		livingRoomLights = domoticz.devices[36]
		--settings
		dimToPercentages = 20
		waitingMinutes = 1
		minimumAmbientLight = 50
		
		-- motion triggered
		if (tonumber(luxLightValue) < minimumAmbientLight and motionSensor.state == 'On') then
			print('motion detected, tun ON the light')
			tvLED.dimTo(dimToPercentages)
			livingRoomLights.switchOn()
			
		end
		
		-- time passed since last movement detected
		if(tvLED.state == "On" and motionSensor.lastUpdate.minutesAgo>waitingMinutes) then
			print('NO motion for long enought, tun OFF the light')
			tvLED.switchOff()
			livingRoomLights.switchOff()
		end
	end
}
Now I go to scripts folder with a smile, vs before when I was going there... without a smile :)
The code looks good to me :)
It is good practice in Lua to define your variables as locals. That way you never accidentally influence other scripts:

Code: Select all

local myVar = 123
And I'd define your constants like this:

Code: Select all

local DIMTO_PERCENTAGES =  = 20
local WAITING_MINUTES = 1
local MINIMUM_AMBIENT_LIGHT = 50

return {
	...
	execute = function(domoticz, motionSensor)
		...
		if (tonumber(luxLightValue) <MINIMUM_AMBIENT_LIGHT and motionSensor.state == 'On') then
		...
	end
}      
      
But that's just a matter of taste and code hygene ;-).

Re: Introducing dzVents - Domoticz Lua file based event scripting made e-z!

Posted: Sunday 13 March 2016 16:39
by dannybloe
Derik wrote:Looks great
What is the simpelst way to start...
Reading the README.md perhaps? :lol:
Seriously, that explains how you can start. I added a quick start section.

Re: Introducing dzVents - Domoticz Lua file based event scripting made e-z!

Posted: Sunday 13 March 2016 17:05
by dannybloe
dakipro wrote:Thanks about the LUX, it works as raw data. How to access temperature, also like raw?
I adjusted the documentation a bit to make this more clear. Many attributes are available by name on the device object like temperature, humidity etc. It is all dependent on what Domoticz passes along to the scripts (otherdevices_<attribute>). However, like Lux, not everything is passed like this (with a name) and in that case the value can be found in the rawData attribute.

I might try to figure out which attributes are available by name and add it to the docs. (or maybe someone already has that list.. hint hint).

Re: Introducing dzVents - Domoticz Lua file based event scripting made e-z!

Posted: Sunday 13 March 2016 18:15
by dannybloe
dannybloe wrote:
dakipro wrote:Thanks about the LUX, it works as raw data. How to access temperature, also like raw?
I adjusted the documentation a bit to make this more clear. Many attributes are available by name on the device object like temperature, humidity etc. It is all dependent on what Domoticz passes along to the scripts (otherdevices_<attribute>). However, like Lux, not everything is passed like this (with a name) and in that case the value can be found in the rawData attribute.

I might try to figure out which attributes are available by name and add it to the docs. (or maybe someone already has that list.. hint hint).
I updated the README and now it lists all attributes that are available. I also updated the API overview. It is sorted now. Easier to find stuff.

Re: Introducing dzVents - Domoticz Lua file based event scripting made e-z!

Posted: Monday 14 March 2016 0:03
by dannybloe
Just published version 0.9.11:
  • Added log method to domoticz object. Using this to log message in the Domoticz log will respect the log level setting in the settings file.
  • Updated documentation. Table of contents, sensor attributes, grouping, sorting etc etc.
  • Added iterator functions (forEach and filter) to domoticz.devices, domoticz.changedDevices and domoticz.variables to iterate or filter more easily over these collections. Starting to look like javascript ;-).
  • Added a couple of example scripts.
forEach

Code: Select all

    domoticz.devices.forEach(function(device)
        if (device.batteryLevel < 20) then
            -- do something
        end
    end)
filter

Code: Select all

    local deadDevices = domoticz.devices.filter(function(device)
        return (device.lastUpdate.minutesAgo > 60)
    end)
    deadDevices.forEach(function(zombie)
        -- do something
    end)
Chain them all:

Code: Select all

    domoticz.devices.filter(function(device)
        return (device.lastUpdate.minutesAgo > 60)
    end).forEach(function(zombie)
        -- do something with the zombie
    end)

Re: Introducing dzVents - Domoticz Lua file based event scripting made e-z!

Posted: Monday 14 March 2016 15:07
by thorbj
I'm trying to make a simple script that alters a virtual switch based on the lux level. I've copied a little from @dakipro's script

Code: Select all

-- DEVICE INDEX
-- 34 = Lux sensor
-- 130 = Low Lux switch


return {
   active = true,			-- set to true to activate this script
   on = {
      34,
      ['timer'] = 'every minute',  -- minutes: xx:00, xx:02, xx:04, ..., xx:58
      
   },

   execute = function(domoticz) 
      --initialize variables
      luxLightValue = domoticz.devices[34].rawData[1] 
      
	  print ('Current lux value: ' ..luxLightValue.. '...')
	  print ('Minimum lux value: 700...')
	  
      -- trigger switch based on lux value
      if (luxLightValue < 700 and domoticz.devices[130] == 'Off') then
         domoticz.devices[130].switchOn()
      end
	  
	  if (luxLightValue > 700 and domoticz.devices[130] == 'On') then
         domoticz.devices[130].switchOff()
      end

   end
}
But I can't get the switch to change. What am I doing wrong?

Heres the log output:

Code: Select all

 2016-03-14 14:56:04.111 LUA: Handling events for: "Lux sensor", value: ""
2016-03-14 14:56:04.111 LUA: =====================================================
2016-03-14 14:56:04.111 LUA: >>> Handler: low lux
2016-03-14 14:56:04.111 LUA: >>> Device: "Lux sensor" Index: 34
2016-03-14 14:56:04.111 LUA: .....................................................
2016-03-14 14:56:04.111 LUA: Current lux value: 1000...
2016-03-14 14:56:04.111 LUA: Minimum lux value: 700...
2016-03-14 14:56:04.111 LUA: .....................................................
2016-03-14 14:56:04.111 LUA: <<< Done
2016-03-14 14:56:04.111 LUA: -----------------------------------------------------
2016-03-14 14:56:04.112 LUA: Handling events for: "Lux sensor_Utility", value: "1000"
2016-03-14 14:56:04.112 LUA: =====================================================
2016-03-14 14:56:04.112 LUA: >>> Handler: low lux
2016-03-14 14:56:04.112 LUA: >>> Device: "Lux sensor" Index: 34
2016-03-14 14:56:04.112 LUA: .....................................................
2016-03-14 14:56:04.112 LUA: Current lux value: 1000...
2016-03-14 14:56:04.112 LUA: Minimum lux value: 700...
2016-03-14 14:56:04.112 LUA: .....................................................
2016-03-14 14:56:04.112 LUA: <<< Done
2016-03-14 14:56:04.112 LUA: ----------------------------------------------------- 
and

Code: Select all

 2016-03-14 15:04:00.449 LUA: Handle timer events
2016-03-14 15:04:00.531 LUA: =====================================================
2016-03-14 15:04:00.531 LUA: >>> Handler: low lux
2016-03-14 15:04:00.531 LUA: .....................................................
2016-03-14 15:04:00.531 LUA: Current lux value: 1000...
2016-03-14 15:04:00.531 LUA: Minimum lux value: 700...
2016-03-14 15:04:00.531 LUA: .....................................................
2016-03-14 15:04:00.531 LUA: <<< Done
2016-03-14 15:04:00.531 LUA: ----------------------------------------------------- 
- Thanks!

Re: Introducing dzVents - Domoticz Lua file based event scripting made e-z!

Posted: Monday 14 March 2016 19:59
by dannybloe
thorbj wrote:

Code: Select all

      if (luxLightValue < 700 and domoticz.devices[130] == 'Off') then
         domoticz.devices[130].switchOn()
      end
	  
	  if (luxLightValue > 700 and domoticz.devices[130] == 'On') then
         domoticz.devices[130].switchOff()
      end
}
Heh.. took me a while to see what's wrong :)
You have to check for the state or bState (boolean) of the device:

Code: Select all

      if (luxLightValue < 700 and domoticz.devices[130].state == 'Off') then
         domoticz.devices[130].switchOn()
      end
	  
	  if (luxLightValue > 700 and domoticz.devices[130].state == 'On') then
         domoticz.devices[130].switchOff()
      end
}
There is no default attribute for devices so you have to pick whatever you want to inspect. Lemme know if that indeed was the problem.

The value of domoticz.devices[130] is that actual table object.

Oh, just a tip for better code readability. I'd do it like this:

Code: Select all

local LUX_SENSOR = 34
lcoal LL_SWITCH = 130

return {
	on...
	active...
	 execute = function(domoticz) 
		local lux = domoticz.devices[34].rawData[1] 
		local llSwitch = domoticz.devices[LL_SWITCH)

		if (lux < 700 and llSwitch.state == 'Off') then
			llSwitch.switchOff()
      		end
     
		if (lux > 700 and llSwitch.state == 'On') then
     			llSwitch.switchOn()
		end
	end
}
I use to define named constants in my code at the top so I can easily adjust them and then use the names in the code so it reads more like sentences with words instead of numbers. I advise to always declare variables as local instead of putting them in the global namespace. You might get side effects you don't expect and it's good code hygiene ;-).

Cheers,

Danny

Re: Introducing dzVents - Domoticz Lua file based event scripting made e-z!

Posted: Monday 14 March 2016 20:37
by thorbj
Thanks Danny! But I'm still unable to get it to work. I've tried with both .state, and .bState.

Code: Select all

-- DEVICE INDEX
-- 34 = Lux sensor
-- 130 = Low Lux switch

local LUX_SENSOR = 34
local LL_SWITCH = 130


return {
   active = true,			-- set to true to activate this script
   on = {
      34,
      ['timer'] = 'every minute',  -- minutes: xx:00, xx:02, xx:04, ..., xx:58
      
   },

   execute = function(domoticz) 
      local lux = domoticz.devices[34].rawData[1]
	  local llSwitch = domoticz.devices[LL_SWITCH)
      
	  print ('Current lux value: ' ..lux.. '...')
	  print ('Minimum lux value: 700...')
	  
      -- trigger switch based on lux value
      if (lux < 700 and llSwitch.state == 'Off') then
         llSwitch.switchOn()
      end
     
     if (lux > 700 and llSwitch.state == 'On') then
         llSwitch.switchOff()
      end

   end
}

Re: Introducing dzVents - Domoticz Lua file based event scripting made e-z!

Posted: Monday 14 March 2016 20:48
by dannybloe
bState is a boolean that evaulates to true or false:

Code: Select all

	if (device.bState) then
		-- bState == true
	end
	
	-- or
	if (device.bState == true) then
		-- true
	end
	
	--or 
	if (not device.bState) then
		-- false
	end
	
	-- or 
	
	if (device.state == 'On') then -- explicitly compare state to the string 'On'
		-- it's on
	end	
Does that help?

Re: Introducing dzVents - Domoticz Lua file based event scripting made e-z!

Posted: Monday 14 March 2016 20:57
by thorbj
Unfortunately not, the script still has no effect on the switch.

Code: Select all

-- DEVICE INDEX
-- 34 = Lux sensor
-- 130 = Low Lux switch

local LUX_SENSOR = 34
local LL_SWITCH = 130

return {
   active = true,			-- set to true to activate this script
   on = {
      LUX_SENSOR,
      ['timer'] = 'every minute',  -- minutes: xx:00, xx:02, xx:04, ..., xx:58
      
   },

   execute = function(domoticz) 
      local lux = domoticz.devices[LUX_SENSOR].rawData[1]
	  local llSwitch = domoticz.devices[LL_SWITCH] 
      
	  print ('Current lux value: ' ..lux.. '...')
	  print ('Minimum lux value: 700...')
	  
      -- trigger switch based on lux value
      if (lux < 700 and (not llSwitch.bState)) then
         llSwitch.switchOn()
      end
     
     if (lux > 700 and llSwitch.bState) then
         llSwitch.switchOff()
      end

   end
}

Re: Introducing dzVents - Domoticz Lua file based event scripting made e-z!

Posted: Monday 14 March 2016 21:32
by dannybloe
thorbj wrote:Unfortunately not, now nothing about this script pops up in the log either.

Code: Select all

	  local llSwitch = domoticz.devices[LL_SWITCH)
Ah crap, my bad. Somehow the error got swallowed (gotta check that one out):

It should be (note the brace at the end):

Code: Select all

	  local llSwitch = domoticz.devices[LL_SWITCH]
and

Code: Select all

local lux = tonumber(domoticz.devices[LUX_SENSOR].rawData[1])
Domoticz passes all the raw stuff as strings :(

I just built in support for a couple of those attributes like lux and now (when I pushed it) you can do this:

Code: Select all

local lux = domoticz.devices[LUX_SENSOR].lux

Re: Introducing dzVents - Domoticz Lua file based event scripting made e-z!

Posted: Monday 14 March 2016 21:45
by thorbj
You are a genius! Now it works perfectly!
Thank you!

v0.9.12

Posted: Monday 14 March 2016 21:56
by dannybloe
Just released 0.9.12:
* Fixed a bug with log level printing. Now errors are printed.
* Added setPoint, heatingMode, lux, WhTotal, WhToday, WActual attributes to devices that support it. No need to access rawData for these anymore.

Due to this log error you didn't see when there were syntax errors in your modules. Now you should see them.

Re: Introducing dzVents - Domoticz Lua file based event scripting made e-z!

Posted: Monday 14 March 2016 22:35
by dakipro
Oh come on... you are now just showing off, making me jealous.. I wish I started this project and became a rockstar :)
Just kidding, you are on fire, excellent real life examples! The "check battery levels" is something I was thinking about making in last 5 months, but I didn't want to start with the "old" plan lua scripting, this is now just to add a new device to the array, the way it should be - plain and simple.

Since the script is now growing and getting a lot more functionality, if I may suggest to start with the some sort of automated testing, just so that script doesn't become a victim of its own success, and overgrows itself and maybe becomes slow or memory demanding.
With some sort of automated tests you can also keep the compatibility with future changes. I think it is important to prevent situation when a new functionality could potentially brake something that was previously working, thus avoiding the situation where people would go back to "plan lua" due to instability.

I think script has so much potential and have a huge "community" sharing their scripts, something we can all benefit from.

Re: Introducing dzVents - Domoticz Lua file based event scripting made e-z!

Posted: Monday 14 March 2016 23:10
by dannybloe
dakipro wrote:Oh come on... you are now just showing off, making me jealous.. I wish I started this project and became a rockstar :)
Just kidding, you are on fire, excellent real life examples! The "check battery levels" is something I was thinking about making in last 5 months, but I didn't want to start with the "old" plan lua scripting, this is now just to add a new device to the array, the way it should be - plain and simple.
Yup I was playing with this idea for almost a year and finally decided to start building it. Glad you like it. (I like it too ;-))
Since the script is now growing and getting a lot more functionality, if I may suggest to start with the some sort of automated testing, just so that script doesn't become a victim of its own success, and overgrows itself and maybe becomes slow or memory demanding.
With some sort of automated tests you can also keep the compatibility with future changes. I think it is important to prevent situation when a new functionality could potentially brake something that was previously working, thus avoiding the situation where people would go back to "plan lua" due to instability.

I think script has so much potential and have a huge "community" sharing their scripts, something we can all benefit from.
Yes, that's my plan as well. I already have tests for the timer stuff. I will start adding tests for the rest. I just takes time. I wanted to have the features in there that i wanted and i think that it's about at that level. I'll fix some bugs if they arise in the coming days and then make a 1.0 I guess. Then I will start added tests.

Re: Introducing dzVents - Domoticz Lua file based event scripting made e-z!

Posted: Tuesday 15 March 2016 9:13
by thorbj
Now I bumped into another obstacle while trying to convert my scripts.
I have this script that check whether I'm home or not and alters a dummy switch based on this.

I have converted most of the script, but I'm stuck on how to work with user vartiables. Like do I still use

Code: Select all

commandArray['Variable:' .. USERVAR] = tostring(no_motion_time)
And can I get values with this string

Code: Select all

no_motion_time = tonumber(uservariables[USERVAR])
Here's the full script: (updated)

Code: Select all

local MOTION = 54
local CELL_ONE = 45
local CELL_TWO = 46
local HOME_SW = 81
local PANASONIC = 119
local USERVAR = 'TimeHjemmeAv'

return {
	active = true,                  -- set to true to activate this script
	on = {
		MOTION,
		CELL_ONE,
		CELL_TWO,
		['timer'] = 'every minute',
	},

	execute = function(domoticz, presenceDevice)

		if (presenceDevice==nil) then
			-- timer was triggered, get my switch
			presenceDevice = domoticz.devices[MOTION,CELL_ONE,CELL_TWO]
		end
		
		local homeSwitch = domoticz.devices[HOME_SW]	
		local no_motion_time = domoticz.variables['USERVAR'].nValue
		local mediaSwitch = domoticz.devices[PANASONIC]
		
		local text_home = '<font color="green">Det er registrert folk hjemme</font>'
		local text_away = '<font color="orange">Det er IKKE registrert folk hjemme</font>'
		
		if (presenceDevice.state == 'On') and (homeSwitch.state == 'Off') then
			homeSwitch.switchOn()
			print(text_home)
		end
		
		if (presenceDevice.state == 'Off') and (mediaSwitch.state == 'Off') then
			no_motion_time = no_motion_time + 1
			else no_motion_time = 0
		end
		
		domoticz.variables['USERVAR'].set(no_motion_time) -- Don't know if this is right??
		
		if (homeSwitch.status == 'On') and (no_motion_time > 5) then
			print(text_away)
			homeSwitch.switchOff()
		end
	end
}
-Thanks

Re: Introducing dzVents - Domoticz Lua file based event scripting made e-z!

Posted: Tuesday 15 March 2016 9:20
by dannybloe
thorbj wrote:

Code: Select all

	
	commandArray['Variable:' .. nomotion_uservar] = tostring(no_motion_minutes)
It is (of course ;-) ) easier than you think:

Code: Select all

	
	domoticz.variables['nomotion_uservar'].set(no_motion_minutes) -- no need to cast to string
RTFM ;-)

And to get a variable:

Code: Select all

	
	local myVar = domoticz.variables['someVar'].value -- or nValue for converted to number version of the value

Re: Introducing dzVents - Domoticz Lua file based event scripting made e-z!

Posted: Tuesday 15 March 2016 9:30
by thorbj
dannybloe wrote:
RTFM ;-)
LOL, yeah I tried, but I probably didn't read thoroughly :oops:

So, just to be sure that I've understood this right, I can use this to get the uservar?

Code: Select all

local USERVAR = 'TimeHjemmeAv'
local no_motion_time = domoticz.variables['USERVAR'].nValue -- nValue instead of tonumber(domoticz.variables['USERVAR']) ??
and this to store the new uservar

Code: Select all

domoticz.variables['USERVAR'].set(no_motion_time)
Sorry, I'm a slow learner on this sort of things :oops:

Re: Introducing dzVents - Domoticz Lua file based event scripting made e-z!

Posted: Tuesday 15 March 2016 9:31
by dannybloe
Yes, that should work :)

Re: Introducing dzVents - Domoticz Lua file based event scripting made e-z!

Posted: Tuesday 15 March 2016 10:21
by thorbj
Thanks!
Does the "domoticz.variables['USERVAR'].set(no_motion_time)" string have to be inside an if statement, or can it be after end - before a new if?

I can't see that the uservar is changing.
I put a

Code: Select all

if (presenceDevice==nil) then
			-- timer was triggered, get my switch
			presenceDevice = domoticz.devices[MOTION,CELL_ONE,CELL_TWO]
		end
in my script. Maybe that broke it?