10.07.2015, 11:12
Here is the example of how to detect different types of pressing on a wall switcher that has no fixation. It was made in collaboration with Embedded Systems specialists and we very appreciate this help.
The use-case we wanted to bring to life is:
1. we have 2 groups of light in the room (e.g. on the ceiling and on the wall)
2. fast double press on the switcher changes state of first group of light and fast single press changes state of second group of light
3. long press turns off both groups
(Our client said that this is rather comfortable to use after couple weeks of testing)
Suppose we have room one with switcher, attached to address 1/1/1 with two groups of light 1/2/1 and 1/2/2, room 2 with switcher 1/1/2 and lights on 1/2/3 and 1/2/4. For every switcher we also need a memory object that has information on how many times was the switcher toggled for last specified period (we use 1 second period). For switcher 1/1/1 we create object 1/3/1 (unsigned integer) and switcher 1/1/2 has corresponded object 1/3/2. Both initialized to zero.
So, here is the code. Resident script, sleeping interval 0. This script handles all telegrams and calls function "switcher" if telegram was from specified address. Function switcher accepts address of the switcher (in format 1_1_1, not 1/1/1 - it is done because string 1_1_1 will be used to store in memory last time of changing state of 1/1/1 object), address of first and second groups of light, counter object (that is described earlier), and new state of switcher (taken from telegram).
Function counts difference between rising and falling edges on the object and detects if the press on the switcher was short or long. In case of short press counter object value increments.
Next event script is to be attached to every counter object. It sleeps for specified interval and after waking up turns on corresponding group of light and resets the counter.
It must be said that you can detect as many toggles as you want for specified period.
The code is not excellent, but it works. I would be very glad to receive advices on optimization.
The use-case we wanted to bring to life is:
1. we have 2 groups of light in the room (e.g. on the ceiling and on the wall)
2. fast double press on the switcher changes state of first group of light and fast single press changes state of second group of light
3. long press turns off both groups
(Our client said that this is rather comfortable to use after couple weeks of testing)
Suppose we have room one with switcher, attached to address 1/1/1 with two groups of light 1/2/1 and 1/2/2, room 2 with switcher 1/1/2 and lights on 1/2/3 and 1/2/4. For every switcher we also need a memory object that has information on how many times was the switcher toggled for last specified period (we use 1 second period). For switcher 1/1/1 we create object 1/3/1 (unsigned integer) and switcher 1/1/2 has corresponded object 1/3/2. Both initialized to zero.
So, here is the code. Resident script, sleeping interval 0. This script handles all telegrams and calls function "switcher" if telegram was from specified address. Function switcher accepts address of the switcher (in format 1_1_1, not 1/1/1 - it is done because string 1_1_1 will be used to store in memory last time of changing state of 1/1/1 object), address of first and second groups of light, counter object (that is described earlier), and new state of switcher (taken from telegram).
Function counts difference between rising and falling edges on the object and detects if the press on the switcher was short or long. In case of short press counter object value increments.
Code:
if not client then
require('genohm-scada.eibdgm')
-- knx group write handler
function groupwrite(event)
local value
value = knxdatatype.decode(event.datahex, dt.bool)
--first room
if event.dst == "1/1/1" then
switcher("1_1_1", "1/2/1", "1/2/2", "1/3/1", value)
end
--second room
if event.dst == "1/1/2" then
switcher("1_1_2", "1/2/3", "1/2/4", "1/3/2", value)
end
-- add the same code for next rooms
end
client = eibdgm:new()
client:sethandler('groupwrite', groupwrite)
function switcher(event_adress, light1, light2, counter_object, value)
nowTIME = os.time()
counter = grp.getvalue(counter_object)
state = value
if (state == false) then
counter = counter + 1
lastONtime = storage.get('lastONtime' .. event_adress)
if (nowTIME - lastONtime > 1) then
log('long press ' .. event_adress)
grp.write(light1, false)
grp.write(light2, false)
grp.update(counter_object, 0)
else
grp.update(counter_object, counter)
end
else
storage.set('lastONtime' .. event_adress, nowTIME)
end
end
end
client:step()
Next event script is to be attached to every counter object. It sleeps for specified interval and after waking up turns on corresponding group of light and resets the counter.
Code:
event_adress = '1/3/1'
light1 = '1/2/1'
light2 = '1/2/2'
switcher_adress = '1/1/1'
os.sleep(1)
value = grp.getvalue(event_adress)
if (value == 1) then
--log('single press '.. switcher_adress)
grp.write(light1, not(grp.getvalue(light1)))
grp.update(event_adress, 0)
end
if (value == 2) then
--log('double ' .. switcher_adress)
grp.write(light2, not(grp.getvalue(light2)))
grp.update(event_adress, 0)
end
if (value >= 3) then
--log('reset counter'.. switcher_adress, value)
grp.update(event_adress, 0)
end
It must be said that you can detect as many toggles as you want for specified period.
The code is not excellent, but it works. I would be very glad to receive advices on optimization.