| 
		
	
	
	
		
	Posts: 58 
	Threads: 19 
	Joined: Nov 2015
	
 Reputation: 
0 
	
	
		Hi,
 Is there an easy way to recognize number of "button presses" in a specific time period.
 
 What I want to do is to apply different scenario if client presses a specific button one time and another scenario if he presses button twice in a defined time interval.
 
 Thanks in advance!
 
		
	 
	
	
	
		
	Posts: 5283 
	Threads: 29 
	Joined: Aug 2017
	
 Reputation: 
237 
	
	
	
	
------------------------------Ctrl+F5
 
		
	 
	
	
	
		
	Posts: 58 
	Threads: 19 
	Joined: Nov 2015
	
 Reputation: 
0 
	
	
		 (04.10.2021, 11:06)p_xatzi Wrote:  Hi,
 Is there an easy way to recognize number of "button presses" in a specific time period.
 
 What I want to do is to apply different scenario if client presses a specific button one time and another scenario if he presses button twice in a defined time interval.
 
 Thanks in advance!
 
Hi, 
 
Thanks for the reply!
 
I have only some basic knowledge of coding so as far as the practical side is concerned let me know if i get it right:
 
   1. I have to program push button to sent 1 on press and 0 on release on knx bus. 
   2. On value 1 of push button telegram (button "press"), time stamp of new event is captured 
   3. On value 0 of push button telegram (button "relased"), counter is increased by 1 and event script is executed. First of all sleep function is activated to wait for the result to come from switcher function for specified period (1 sec). 
   4. After this period (1 sec) the result (that is edje down ("realeases") detections) is read. If time period has expired the result will be 0.
  
May I ask: 
In case of 2nd edje down detection during period, due to new event script call, the desired command will be executed 1 sec later.  
So, suppose we have second pulse edje detection almost at the end of time period is it true that a slight delay (of 1 sec) may be present? 
 
I will test and ask for more help is something goes wrong. 
 
Thanks again!
	 
		
	 
	
	
	
		
	Posts: 58 
	Threads: 19 
	Joined: Nov 2015
	
 Reputation: 
0 
	
	
		Hi again, 
Based on the proposed solution
(https://forum.logicmachine.net/showthrea...d=74#pid74) 
and thread:
https://forum.logicmachine.net/showthrea...4#pid15204 
I have made a edje detection group of scripts which I attach.
 
'Resident (edje detection).lua' detects and counts pulses. When new pulse is present, a timer is created with help of 'common function.lua' and a corresponding 'timer off' is triggered with help of 'Resident Timer Off.lua' script. In the meanwhile new pulses are counted. At the timeout of timer the 'Typical Event Script.lua' is triggered with value of counter at that time and thus the proper action is executed. 
 
The scripts work really well and detect concurrent pulses from different G.A. Also, when long pressing a button you don' t have to release it in order to execute the action. In addition you can set different timeout for each G.A.
 
However the issue I have is that it takes more than a second to apply action. 
The scripts work only then setting 'Resident Timer Off.lua' with sleep time 1sec. So, I guess that this is the reason for longer delay. If I set 0 it does not work properly.
 
So, question is: 
- Is it possible to set multiple resident scripts with sleep time 0 and if yes what is the reason for improper function in my case. 
- Is there any way to reduce edge detection and corresponding actions to fractions of 1 sec. 
- Is it possible to dublicate 'Resident (edje detection).lua' and run in parallel in order to organize the edge detections (lights and scenes).
 
Thanks in advance!
		
	 
	
	
	
		
	Posts: 8410 
	Threads: 45 
	Joined: Jun 2015
	
 Reputation: 
481 
	
	
		This won't work correctly. If a resident script with group monitoring has 1 second sleep time it means that this script can only process 1 telegram per second. All other telegrams will be queued and it will lead to larger delays later on.I'll provide a working example later.
 
		
	 
	
	
	
		
	Posts: 8410 
	Threads: 45 
	Joined: Jun 2015
	
 Reputation: 
481 
	
	
		Resident script with sleep time set to 0. You only need to edit the config  table. You will need to restart the script via disable/enable after each config edit. In the config table each key is a group address which sends 1 on button press and 0 on button release. Value for each key is another table with the button configuration. This way you only need a single script for all buttons with multiple press functionality.
 Code: if not client thenconfig = {
 ['0/0/1'] = {
 timeout = 0.5,
 longpress = 1,
 press = function(ptype, count)
 local light1 = '1/1/1'
 local light2 = '1/1/2'
 
 if ptype == 'short' then
 if count == 1 then
 grp.write(light1, not grp.getvalue(light1))
 else
 grp.write(light2, not grp.getvalue(light2))
 end
 else
 grp.write(light1, false)
 grp.write(light2, false)
 end
 end
 },
 ['1/1/3'] = {
 timeout = 0.5,
 press = function(ptype, count)
 log('press 1/1/3', ptype, count)
 end
 }
 }
 
 function groupwrite(event)
 local cfg = config[ event.dst ]
 
 if cfg then
 cfg.pressed = tonumber(event.datahex, 16) ~= 0
 
 if cfg.pressed then
 cfg.timer = 0
 cfg.count = (cfg.count or 0) + 1
 end
 end
 end
 
 function press(cfg, ptype, count)
 if type(cfg.press) == 'function' then
 cfg.press(ptype, count)
 end
 
 cfg.pressed = false
 cfg.timer = nil
 cfg.count = 0
 end
 
 client = require('localbus').new(0.1)
 client:sethandler('groupwrite', groupwrite)
 end
 
 ts, tu = os.microtime()
 client:loop(0.2)
 diff = math.max(0, os.udifftime(ts, tu))
 
 for addr, cfg in pairs(config) do
 if cfg.timer then
 cfg.timer = cfg.timer + diff
 
 if cfg.pressed then
 if cfg.longpress and cfg.timer >= cfg.longpress then
 press(cfg, 'long')
 end
 elseif cfg.timer >= (cfg.timeout or 1) then
 press(cfg, 'short', cfg.count)
 end
 end
 end
		
	 
	
	
	
		
	Posts: 58 
	Threads: 19 
	Joined: Nov 2015
	
 Reputation: 
0 
	
		
		
		26.10.2021, 09:31 
(This post was last modified: 26.10.2021, 09:32 by p_xatzi.)
		
	 
		Thanks admin!
I will check in the following days and come back with some questions because I don' t really know how to code.
However, right now I'd like to ask if it is possible to have multiple resident scripts running at 0 sleep time. If yes is there any way to have a standard running order.
Resident scripts with 1 sec sleep time work as expected for the following thread?
Thanks in advance!
 
		
	 
	
	
	
		
	Posts: 8410 
	Threads: 45 
	Joined: Jun 2015
	
 Reputation: 
481 
	
	
		You can have multiple resident scripts with 0 sleep time but make sure that they don't consume all CPU with busy loops. In the previous script most of time is spent inside the client:loop(0.2) call. The script is in a waiting state until a telegram arrives or a timeout happens so there's no busy loops there.There's no defined execution order for any scripts.
 Polling resident scripts (for example, reading storage data) with a sleep time of 1 or more is generally OK.
 
		
	 
	
	
	
		
	Posts: 58 
	Threads: 19 
	Joined: Nov 2015
	
 Reputation: 
0 
	
		
		
		31.10.2021, 22:15 
(This post was last modified: 31.10.2021, 22:45 by p_xatzi.)
		
	 
		Thanks admin! It works perfectly! Great implementation! 
Is it possible to explain shortly why different modules were used in first and your solution? Are there any differences in performance or is it just that in second case we want to loop in predefined time intervals?
 Code: -- Implementation with module 'genohm-scada.eibdgm'--------------------------------------------------
 if not client then
 require('genohm-scada.eibdgm')
 
 -- knx group write handler
 function groupwrite(event)
 end
 
 client = eibdgm:new()
 client:sethandler('groupwrite', groupwrite)
 end
 
 client:step()
 
 
 -- Implementation wih module 'localbus'
 ---------------------------------------
 if not client then
 
 function groupwrite(event)
 end
 
 client = require('localbus').new(0.1)
 client:sethandler('groupwrite', groupwrite)
 end
 
 client:loop(0.2)
		
	 
	
	
	
		
	Posts: 8410 
	Threads: 45 
	Joined: Jun 2015
	
 Reputation: 
481 
	
	
		localbus is the new library version. The old one is just a compatibility layer for old scripts which uses localbus internally.
	 
		
	 
	
	
	
		
	Posts: 58 
	Threads: 19 
	Joined: Nov 2015
	
 Reputation: 
0 
	
	
		Hi, 
In the above script created by admin I would like to control scenes sequence (order and delay) between scenes for the same G.A. instance like below.
 
Is it possible to implement this with 'os.sleep' function as below?
 
Is there any way I could control scene sequence (order and delay) when multiple scenes should run with same command. 
 
Thanks in advance!
    
 Code: -- ΣΚΗΝΗ @H - H - Leave Home for a while['20/1/130'] = {
 timeout = 0.5,
 longpress = 5,
 press = function(ptype, count)
 
 if ptype == 'short' then
 if count == 1 then
 scene.run('@H - R1 - Leave Home for a while - Lights')
 scene.run('@H - R2 - Leave Home for a while - Lights')
 scene.run('@H - R3 - Leave Home for a while - Lights')
 scene.run('@H - R4 - Leave Home for a while - Lights')
 scene.run('@H - R5 - Leave Home for a while - Lights')
 scene.run('@H - R6 - Leave Home for a while - Lights')
 
 os.sleep(0.2)
 
 scene.run('@H - G_LR/DR/KTC/COR - Leave Home for a while - Lights')
 scene.run('@H - B1_LR - Leave Home for a while - Lights')
 scene.run('@H - F1_COR - Leave Home for a while - Lights')
 scene.run('@H - LDR/RF - Leave Home for a while - Lights')
 --scene.run('@H - H - Leave Home for a while - Outside Lights')
 elseif count == 2 then
 scene.run('@H - R1 - Leave Home for a while - Lights')
 scene.run('@H - R2 - Leave Home for a while - Lights')
 scene.run('@H - R3 - Leave Home for a while - Lights')
 scene.run('@H - R4 - Leave Home for a while - Lights')
 scene.run('@H - R5 - Leave Home for a while - Lights')
 scene.run('@H - R6 - Leave Home for a while - Lights')
 scene.run('@H - G_LR/DR/KTC/COR - Leave Home for a while - Lights')
 scene.run('@H - B1_LR - Leave Home for a while - Lights')
 scene.run('@H - F1_COR - Leave Home for a while - Lights')
 scene.run('@H - LDR/RF - Leave Home for a while - Lights')
 --scene.run('@H - H - Leave Home for a while - Outside Lights')
 scene.run('@H - H - Leave Home for a while - Curtains')
 end
 
 elseif ptype == 'long' then
 scene.savelive('@H - R1 - Leave Home for a while - Lights')
 scene.savelive('@H - R2 - Leave Home for a while - Lights')
 scene.savelive('@H - R3 - Leave Home for a while - Lights')
 scene.savelive('@H - R4 - Leave Home for a while - Lights')
 scene.savelive('@H - R5 - Leave Home for a while - Lights')
 scene.savelive('@H - R6 - Leave Home for a while - Lights')
 scene.savelive('@H - G_LR/DR/KTC/COR - Leave Home for a while - Lights')
 scene.savelive('@H - B1_LR - Leave Home for a while - Lights')
 scene.savelive('@H - F1_COR - Leave Home for a while - Lights')
 scene.savelive('@H - LDR/RF - Leave Home for a while - Lights')
 --scene.savelive('@H - H - Leave Home for a while - Outside Lights')
 scene.savelive('@H - H - Leave Home for a while - Curtains')
 end
 
 end
 },
		
	 
	
	
	
		
	Posts: 8410 
	Threads: 45 
	Joined: Jun 2015
	
 Reputation: 
481 
	
	
		You should not use sleep there as it will block the whole script. What you can do is create an event script which is triggered by single/double/long press. Then this event script will run other scenes as needed.
	 
		
	 
	
	
	
		
	Posts: 58 
	Threads: 19 
	Joined: Nov 2015
	
 Reputation: 
0 
	
	
		 (20.04.2022, 07:36)admin Wrote:  You should not use sleep there as it will block the whole script. What you can do is create an event script which is triggered by single/double/long press. Then this event script will run other scenes as needed. 
Thanks admin!
	 
		
	 |