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: 4663
Threads: 24
Joined: Aug 2017
Reputation:
213
------------------------------
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: 7782
Threads: 42
Joined: Jun 2015
Reputation:
448
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: 7782
Threads: 42
Joined: Jun 2015
Reputation:
448
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 then
config = {
['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: 7782
Threads: 42
Joined: Jun 2015
Reputation:
448
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: 7782
Threads: 42
Joined: Jun 2015
Reputation:
448
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: 7782
Threads: 42
Joined: Jun 2015
Reputation:
448
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!
|