Page 11 of 17

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

Posted: Tuesday 19 April 2016 7:53
by dannybloe
Eduard wrote:
dannybloe wrote:How do we get to the id of a scene or a group? It isn't part of the otherdevices_idx table but I do need it for completeness. I can still get that from the http data or you should create a table like otherdevices_groupsandscenes_idx or something like that.
How do you get them for devices? Via the http data? If yes, i propose to get them for scenes/groups also via http data.

For devices there is a otherdevices_idx table. So yeah, for groups and scenes I now take it from the http data. That data is merged with the current state values from otherdevices_scenesandgroups so you always have the latest state. Works for now :)
dannybloe wrote:And.. I want to have scenes and groups split so I can create domoticz.scenes[<name>/<id>] and domoticz.groups[<name>/<id>]. So I need a way to distinguish these two. If they are all in one table then I still cannot make that distinction without using the http data.
It's ok by me to split those... If you do a http data with json.htm?type=devices&displayhidden=1&filter=all&used=true, you can look at the "Type" tag. For scenes it is "Scene" and for groups "Group" :D

Code: Select all

      {
         "Data" : "Mixed",
         "Description" : "",
         "Favorite" : 0,
         "LastUpdate" : "2016-03-17 12:35:42",
         "Name" : "Scene1",
         "PlanID" : "",
         "PlanIDs" : [ 0 ],
         "Protected" : false,
         "Status" : "Mixed",
         "Type" : "Scene",
         "TypeImg" : "scene",
         "UsedByCamera" : false,
         "XOffset" : 0,
         "YOffset" : 0,
         "idx" : "1"
      },
      {
         "Data" : "Off",
         "Description" : "",
         "Favorite" : 0,
         "LastUpdate" : "2016-02-06 16:57:47",
         "Name" : "Group1",
         "PlanID" : "",
         "PlanIDs" : [ 0 ],
         "Protected" : false,
         "Status" : "Off",
         "Type" : "Group",
         "TypeImg" : "group",
         "UsedByCamera" : false,
         "XOffset" : 0,
         "YOffset" : 0,
         "idx" : "2"
      }
Yes, I know that. It's already done in the dev branch.

1.0-beta1

Posted: Tuesday 19 April 2016 8:47
by dannybloe
Hi folks,

Today I tagged the dev branch of dzVents which should be the 1.0 beta 1. I think it is feature complete (duh ;-)) enough for a 1.0 release. Of course it is still beta so please test.

I am excited to announce a couple of really cool (if I may say) new features. Taken from the history.txt:
  • Added data persistence for scripts between script runs (see readme for more info)
  • Added a time-line based data type for you scripts with historical information and many statistical functions for retreiving information like average, minumum, maximum, delta, data smoothing (averaging values over neighbours) etc. See readme for more information.
  • Added SMS method to the domoticz object.
  • Added toggleSwitch() method to devices that support it.
  • Added more switch states that control device.bState (e.g. on == true, open == true 'all on' == true)
  • Added secondsAgo to the lastUpdate attribute
  • Added tests (test code coverage is above 96%!)
  • Refactored code significantly.
  • Made sure differently formulated but equal triggers in one script only execute the script only once (like MySensor and MySensor_Temperature).
  • Added trigger info as a third parameter (Lua table) that is passed to the execute method of a script containing information about what exactly triggered the script (type = EVENT_TYPE_TIMER/EVENT_TYPE_DEVICE, trigger=<timer rule>). See readme.
  • Added Lua time properties to domoticz.time property with all information about the current time (hours, minutes, seconds, etc.)
  • Added option to return false in a forEach iteratee function which will abort the forEach loop.
  • All devices not delivered by Domoticz to the event scripts are now added to domoticz.devices using the http data that is fetched every 30 minutes (by default).
  • Added scenes and groups collections to the domoticz object
  • Added Quick Reference Guide.
So to me the most interesting part is the persistent variables stuff. You can now define variables in your scripts that hold their value between script runs. Simply define them in your script file like this:

Code: Select all

return {
    active = true,
    on = {
        'MySwitch'
    },
    data = { 
        counter = {initial=0} 
    },
    execute = function(domoticz, switch)
        if (domoticz.data.counter = 5) then
            domoticz.notify('The switch was pressed 5 times!')
            domoticz.data.counter = 0 -- reset the counter
        else
            domoticz.data.counter = domoticz.data.counter + 1
        end
    end
}
In this simple example I defined a persistent counter.

You can even create global variables like this. Simply create a script file called global_data.lua and place next to your other script files. Defining globals is quite similar:

Code: Select all

return {
    data = {
        peopleAtHome = { initial = false },
        heatingProgramActive = { initial = false }
    }
}
And then accessing them in your script goes like this (don't mind the usefulness of this script though ;-)):

Code: Select all

return {
    active = true,
    on = {
        'WindowSensor'
    },
    execute = function(domoticz, windowSensor)
        if (domoticz.globalData.heatingProgramActive and windowSensor.state == 'Open') then
            domoticz.notify("Hey don't open the window when the heating is on!")
        end
    end
}
But what is even more interesting are the persistent variables defined with the type history=true flag! These variables have a time-line based internal history of previous values. You can put whatever you like in there and it acts as a FIFO queue (first in first out). So the historical set is limited in size (for performance reasons of course, fully configurable by you, see the specs). But it allows you to do really cool things like inspecting how fast a temperature rose or what the previous maximum humidity was in the past and a lot lot more:

Code: Select all

return {
    active = true,
    on = {
        'MyTempSensor' -- the trigger
    },
    data = {
        temperatures = { history = true, maxHours = 12 } -- only log values younger than 24 hours
    },
    execute = function(domoticz, sensor)
        -- add new data
        domoticz.data.temperatures.setNew(sensor.temperature)

        -- average
        local average = domoticz.data.temperatures.avg()

        -- maximum value in the past hour:
        local max = domoticz.data.temperatures.maxSince('01:00:00') 
    end
}
Here is a list functions you can call on these variables:
  • avg( [fromIdx], [toIdx], [default] )
  • avgSince( timeAgo, default )
  • delta( fromIdx, toIdx, [smoothRange], [default] )
  • deltaSince( timeAgo, [smoothRange], [default] )
  • get( [idx] )
  • getAtTime( timeAgo )
  • filter(function)
  • find(function)
  • forEach(function)
  • getLatest( )
  • getOldest( )
  • localMin( [smoothRange], default )
  • localMax([smoothRange], default)
  • max( [fromIdx], [toIdx] )
  • maxSince( timeAgo )
  • min( [fromIdx], [toIdx] )
  • minSince( timeAgo )
  • setNew(data)
  • size
  • subset( [fromIdx], [toIdx] )
  • subsetSince( [timeAgo] )
  • reduce(function, initial)
  • reset( )
  • smoothItem(itemIdx, [smoothRange])
  • sum( [fromIdx], [toIdx] )
  • sumSince( timeAgo )
Yes, you are correct: it can even do data-smoothing which may be useful for calculating deltas or comparing data.
smoothing.png
smoothing.png (34.39 KiB) Viewed 4341 times
(The red line is the raw data with spikes, the other lines with smoothRange=1 and 2).

And of course you don't have to put just numbers is such a variable. It can be anything but then of course some of these functions are irrelevant.

So... please take some time to read the doc and hopefully there's something in there that makes scripting even easier that it was before. At least it may reduce the amount of coding that you have to do to.

Oh, small note. These historical variables are in no way suitable for full data logging of your entire domoticz environment. Only create these variables when you need them for your scripts and keep them as small as possible. I suspect that the reset() method is some interesting method that can be called in many situations when historical values are not needed anymore (maybe as soon as the heater is turned on). If you store a year worth of data from a sensor that logs every 10 seconds then I can assure you that your scripts will not run :-D. The data is stored in files (one for each script) in a subfolder inside your script folder. See how it works.

Oh and I still have to write some examples that use these features. And please let me know if you have some cool (not too complex) implementations or applications using these variables. I have made the historical stuff quite generic hoping it will trigger the creativity of you as script writer but of course I can only think of my own situations. So I'm curious what use it may be for you (or not perhaps).

And if you think something is still missing let me know as well or make a pull request yourself (the code is quite readable I believe).

Cheers,

Danny

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

Posted: Tuesday 19 April 2016 9:04
by NietGiftig
Thanks, it has truly become complete.
I hope indeed that you put some simple and clean examples in.

I hope that others also dzVentilate (pun intended) their scripts here or in the git.

Re: 1.0-beta1

Posted: Tuesday 19 April 2016 11:25
by Eduard
dannybloe wrote: Added scenes and groups collections to the domoticz object
Note: Status of Groups & Scene won't work in the latest stable yet, until Pull Request 617 has been merged with the Domoticz-master branch...

Re: 1.0-beta1

Posted: Wednesday 20 April 2016 7:55
by dannybloe
Eduard wrote:
dannybloe wrote: Added scenes and groups collections to the domoticz object
Note: Status of Groups & Scene won't work in the latest stable yet, until Pull Request 617 has been merged with the Domoticz-master branch...
It does work but the states for the groups and scenes are then taken only from the http data which may not be as old as the refresh interval (30 minutes by default). I check for the existence of that new table.

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

Posted: Wednesday 20 April 2016 13:16
by mcmacpl
I noticed that for my lux sensors device.lux does not work (contains nothing), while tonumber(device.rawData[1]) works well. What could be the reason?

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

Posted: Wednesday 20 April 2016 13:46
by dannybloe
Can you check if there is data in devices.lua as that is where the info is taken from (partly).

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

Posted: Wednesday 20 April 2016 15:22
by mcmacpl
No, there isn't. Maybe because I switched off http data fetching :-)

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

Posted: Wednesday 20 April 2016 17:44
by dannybloe
Hehe... there is no way of knowing that the raw values contain lux values unless I know what the type of the device is. And that information is only available through the http json data. Alas....

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

Posted: Tuesday 26 April 2016 13:14
by Nautilus
Westcott wrote:
I tried some lua json decoders and encoders but they didn't like the long dumps coming from Domoticz. What decoder is this?
It's the JSON.lua utility as described somewhere in the Wiki, and is loaded into the Lua script by the call -
json = (loadfile "/home/pi/domoticz/scripts/lua/JSON.lua")()

The JSON call and decode takes less than 1 second.
Sorry the off-topic but do you know what could be the reason when for example decoding Wunderground json data works fine, but if I try to decode the Domoticz json output (e.g. just for one device, from http://DOMOURL/json.htm?type=devices&rid=IDX) it always fails with "Error: EventSystem: Warning!, lua script SCRIPT has been running for more than 10 seconds" and no output from the decode operation. If I request to print the whole json output it does it, but it takes over 10 seconds in this case as well. If I try to print the decoded value -> nothing.

With Wunderground it is pretty much instant. And yes I'm using the JSON.lua file as well...

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

Posted: Saturday 30 April 2016 20:50
by dannybloe
Please stay on topic (as it is already a large topic). You can pm people directly with this question :)

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

Posted: Monday 02 May 2016 14:49
by ben92
Hi,

Since update with last beta 5096, i think dzVents is logging too much or perhaps a bug (dont know) : http://www.domoticz.com/forum/viewtopic.php?f=6&t=11794

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

Posted: Monday 02 May 2016 15:01
by dannybloe
Can you try the dev branch in github? That should test for this new scenesgroups Lua table that Domoticz creates in the latest versions.

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

Posted: Monday 02 May 2016 15:08
by ben92
OK thanks, i will try tonight...

Nice it works.

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

Posted: Tuesday 03 May 2016 0:54
by sbisbilo
Hi,

I'm trying dzVents to replace my LUA scripts but I don't understand everything !
For example, I'd like to convert this :

Code: Select all

commandArray = {}
if (otherdevices['Alarme activee'] == 'On' ) and (devicechanged['Capteurs'] == 'On' ) then
    commandArray['Detection']='On'
end
return commandArray
But I don't know how to put 2 conditions if device1 = 'on' (already active) and device2 change to 'on' then device 3 = 'on'

Can you help me please ?

Thanks
Sbisbilo

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

Posted: Wednesday 04 May 2016 12:05
by dannybloe
sbisbilo wrote:Hi,

I'm trying dzVents to replace my LUA scripts but I don't understand everything !
For example, I'd like to convert this :

Code: Select all

commandArray = {}
if (otherdevices['Alarme activee'] == 'On' ) and (devicechanged['Capteurs'] == 'On' ) then
    commandArray['Detection']='On'
end
return commandArray
But I don't know how to put 2 conditions if device1 = 'on' (already active) and device2 change to 'on' then device 3 = 'on'

Can you help me please ?

Thanks
Sbisbilo
Hi Sbisbillo,

By just looking at that tiny piece of code you pasted I can say this is how you do it:

Code: Select all

if (domoticz.devices['Alarme activee'].state == 'On' and domoticz.devices['Capteurs'].changed) then
	domoticz.devices['Detection'].switchOn()
end
However, I assume this code is triggered by some event so perhaps you could create a dzVents script like this:

Code: Select all

return {
	active = true,
	on = {
		'Capteurs' 
	},
	execute = function(domoticz, capteursDevice, triggerInfo)
	
		if (domoticz.devices['Alarme activee'].state == 'On') then
			domoticz.devices['Detection'].switchOn()
		end		
		
	end
}
In this example, the script is only executed when Capteurs was changed. So inside the script you only have to check if the alarm is active and if so, switchOn the detection device.

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

Posted: Thursday 05 May 2016 9:35
by sbisbilo
Thanks dannybloe, I'm gonna try this :D
And nice work by the way !

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

Posted: Thursday 05 May 2016 20:22
by dannybloe
Thanks and let me know if it works.

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

Posted: Sunday 22 May 2016 12:22
by fhwessels
Hi what will the time setting be to only set an light on between 00:00 and 6:00 in the morning. I don't seem to get this right.If there is movement between this time then only set the light on for only for 1 min and then off. Here is what I have.

Code: Select all

return{
active = true,

on = {
      236,    -- index of the device -  LED 237 PIR 236
	 
     
	   ['timer'] = {
			'at 00:00',
			'at 06:00'		
		}
		 
		},
		
   execute = function(domoticz, mySwitch) -- see readme for what you get
      if (domoticz.devices[236].state == 'On') then
         domoticz.devices[237].dimTo(20)
      end
      if(domoticz.devices[236].lastUpdate.minutesAgo > 1) then
         domoticz.devices[237].switchOff()
      end
   end
   }

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

Posted: Sunday 22 May 2016 18:28
by dannybloe
fhwessels wrote:Hi what will the time setting be to only set an light on between 00:00 and 6:00 in the morning. I don't seem to get this right.If there is movement between this time then only set the light on for only for 1 min and then off. Here is what I have.

Code: Select all

return{
active = true,

on = {
      236,    -- index of the device -  LED 237 PIR 236
	 
     
	   ['timer'] = {
			'at 00:00',
			'at 06:00'		
		}
		 
		},
		
   execute = function(domoticz, mySwitch) -- see readme for what you get
      if (domoticz.devices[236].state == 'On') then
         domoticz.devices[237].dimTo(20)
      end
      if(domoticz.devices[236].lastUpdate.minutesAgo > 1) then
         domoticz.devices[237].switchOff()
      end
   end
   }
Ah, well, timer events are separate from device events. So, when there is movement detected, the script is always executed. No matter what time of day it is. The timer setting makes the script run every minute between 00:00 and 06:00, no matter if there is movement detected.

So, until I make this feature (which is an interesting idea) you have to check the time yourself (and remove the timer setting completely). You can use dzVents domoticz.time property:

Code: Select all

	
	if (domoticz.time.hour > 0 and domoticz.time.hour < 6) then 
		...
	end
	

But it would be nice if you can define a trigger and combine a time constraint. I'll consider it for 1.1.