Posts: 22
Threads: 4
Joined: Nov 2019
Reputation:
0
I use the Staircase script frequently. Thanks again!
Now I would like to use it also in rooms where by default a dimmed lamp burns softly (e.g. 30%), for example in the hallway. When the motion detector of the alarm detects someone in the hallway, I would like the lamp to burn brighter for a defined time (e.g. 90% for 60 seconds). And then back to the old dimming value (30%).
If the lamp is turned off in the meantime, it should go out and turn on again the next time in the dimming mode (30%). I've tried all kinds of things, but can't get it to work properly.
Every time it seems to work, but then there is still an error somewhere. And I have solved it with three different scripts. It is complex to explain. Can someone please modify the script in such a way that this does work properly? Hopefully more people will enjoy this enhanced script .
Thanks in advance!
Posts: 7775
Threads: 42
Joined: Jun 2015
Reputation:
447
Can you post the scripts that you are using now?
Posts: 22
Threads: 4
Joined: Nov 2019
Reputation:
0
19.05.2022, 18:52
(This post was last modified: 19.05.2022, 18:57 by Dirk79.)
(16.03.2022, 09:25)admin Wrote: Can you post the scripts that you are using now?
Thanks for the question and apologies for not responding sooner. I did not notice your response.
I created two different scripts. The first one responds to the PIR. For that, I modified the beautiful Staircase logic. See my explanation in the script. I added a lot of logs to find for myself why it doesn't work properly.
With the second script I want to achieve that if the lamp is turned off (manually or by a program or by another script), that the running first script then stops, that the lamp goes off, and the next time it comes on again dimmed.
In practice, it works well, until we go to bed. Usually the lamp goes off first and then on again. Also, regularly the lamp goes directly on at the brighter setting. So then the brighter setting is the same as the standard setting.
It would be best if this could work with just 1 script. I would like to use this script in more places in the house (and especially outside).
Here are the scripts:
SCRIPT 1:
Code: -- Note that at 3/0/7 there is also a script, which should stop this staircase if the lamp is turned on/off.
-- Only react to PIR going on, not going off:
inputvalue = event.getvalue
if (event.getvalue() == false or event.getvalue() == 0) then
return
end
-- ** Staircase logic with external time object and retriggering on input object Version 3.1 ** --
-- ****************************** Created by Erwin van der Zwart **************************** --
-- ************************************** SET PARAMETERS ************************************ --
-- Set input address
AddressInput = '9/0/1'
-- Set output address
AddressOutput = '1/1/7'
-- Set unique name for staircase timer (to avoid same storage name usage)
StaircaseName = 'PIR_LAMP_HAL'
-- Set external time address (optional)
AddressExternalTime = ''
-- Use time left indication
UseTimeLeft = false -- Set to true if time left indication will be used
-- Set feedback adress of time left indication (optional)
AddressTimeLeft = ''
-- Set time delay (Used when external time is not available)
SetDelay = 15
-- Seconds or Minutes
SetSec = true-- Set to false for Minutes
-- Set factor delay (Multiplies Delay)
SetFac = 1
-- Logic can be turned of by value 0
Off_by_Value_Zero = false
-- Additions for brightening the lamp on motion dd 14-01-2022:
Schemer = grp.getvalue('6/0/6') -- If it is dusk, this is set to 1.
AanStandHal = grp.getvalue('3/0/7') -- This indicates whether lamp is on when the script starts.
DimStandHal = grp.getvalue('3/2/7') -- This is the dimming value at the start of the script.
AdressOpgeslagenBeginStandHal = '1/2/7'-- Dim value field especially for this script to save initial state (I don't manage to keep this in memory)
OpgeslagenBeginStandHal = grp.getvalue(AdressOpgeslagenBeginStandHal)
TijdelijkHarderHal = grp.getvalue('39/1/1') -- This contains the (brighter) dimming value that the lamp should temporarily be at (e.g. 90%)
-- If DimStandHal is set to 0, the lamp is off, and nothing needs to happen. Nothing needs to happen when there is no twilight either.
if (DimStandHal) == 0 or (Schemer) == false then
--log('return because hall lamp not on or no dusk')
return
end
-- If DimStandHal == TemporaryHarderHal, then the script has run before. Then nothing should happen. Otherwise save current value.
if DimStandHal == TijdelijkHarderHal then
--log ('DimStandHal gelijk aan TijdelijkeHarderHal')
--log ('OpgeslagenBeginStandHal is'..OpgeslagenBeginStandHal)
--log ('TijdelijkHarderHal is'..TijdelijkHarderHal)
-- do nothing
else
grp.write(AdressOpgeslagenBeginStandHal, DimStandHal)
OpgeslagenBeginStandHal = grp.getvalue(AdressOpgeslagenBeginStandHal)
--log ('Nieuwe start script (Else)')
--log ('OpgeslagenBeginStandHal is'..OpgeslagenBeginStandHal)
--log ('DimStandHal is'..DimStandHal)
--log ('TijdelijkHarderHal is'..TijdelijkHarderHal)
end
-- ************************************** END PARAMETERS ************************************ --
-- *************************** DON'T CHANGE ANYTHING UNDER THIS LINE ************************ --
inputvalue = event.getvalue
if Off_by_Value_Zero == false and (event.getvalue() == false or event.getvalue() == 0) then
-- Exit script
return
end
ValueInput = grp.getvalue(AddressInput)
ValueOutput = grp.getvalue(AddressOutput)
ValueExternalTime = grp.getvalue(AddressExternalTime)
if SetSec == true then
SetSeconds = 1
else
SetSeconds = 60
end
if ValueExternalTime == nil then
ValueExternalTime = 0
end
if ValueExternalTime > 0 then
StairCaseTime = ValueExternalTime * SetSeconds * SetFac
else
StairCaseTime = SetDelay * SetSeconds * SetFac
end
if ValueInput == true then
--check for earlier started scrips
--check storage for stpid value
stpid = storage.get(StaircaseName)
--check if stpid has a value
if stpid == nil then
pid = os.getpid()
storage.set(StaircaseName, pid)
else
-- kill earlier running script
os.kill(stpid, signal.SIGKILL)
-- create new pid for next time to kill
pid = os.getpid()
storage.set(StaircaseName, pid)
end
if ValueOutput < TijdelijkHarderHal then
grp.write(AddressOutput, TijdelijkHarderHal)
ValueOutput = true
end
-- Check time left indication is used
if UseTimeLeft == true then
if StairCaseTime > 0 then
grp.update(AddressTimeLeft, StairCaseTime)
repeat
StairCaseTime = StairCaseTime - 1
grp.update(AddressTimeLeft, StairCaseTime)
os.sleep(1)
until StairCaseTime == 0
end
else
os.sleep(StairCaseTime)
end
ValueOutput = grp.getvalue(AddressOutput)
if ValueOutput == TijdelijkHarderHal then
ValueInput = grp.getvalue(AddressInput)
if ValueInput == true then
grp.write(AddressInput, false)
ValueInput = false
end
if Off_by_Value_Zero == false then
if ValueOutput == TijdelijkHarderHal then
grp.write(AddressOutput, OpgeslagenBeginStandHal) -- value here was 0, but to OpgeslagenBeginStandHal to set it back to this position.
ValueOutput = 0
end
else
-- Do nothing, this will trigger else condition below on next run
end
end
else
--check for earlier started scrips
--check storage for stpid value
stpid = storage.get(StaircaseName)
--check if stpid has a value
if stpid == nil then
else
-- kill earlier running script
os.kill(stpid, signal.SIGKILL)
grp.update(AddressTimeLeft, 0)
pid = nil
storage.set(StaircaseName, pid)
end
-- Terugschrijven naar beginstand
if ValueOutput == TijdelijkHarderHal then
--log ('ValueOutput == TijdelijkHarderHal')
grp.write(AddressOutput, OpgeslagenBeginStandHal)
end
end
SCRIPT 2:
Code: --When switching this lamp, any running script on the hall PIR (9/0/1) is stopped.
--This script is activacted at 3/0/7 and 0/1/1 (group lighting downstairs)
StaircaseName = 'PIR_LAMP_HAL'
stpid = storage.get(StaircaseName)
os.kill(stpid, signal.SIGKILL)
grp.update(AddressTimeLeft, 0)
pid = nil
storage.set(StaircaseName, pid)
-- If script is turned off, while the lamp is louder during the PIR script, then the "old" DimValue must be written over the feedback.
-- The idea is that the lamp then starts up the next time with the harder setting (on which it went out) and then automatically dims back to the old dimming value.
OpgeslagenDimWaarde = grp.getvalue('1/2/7')
grp.write('3/2/7', OpgeslagenDimWaarde)
Posts: 7775
Threads: 42
Joined: Jun 2015
Reputation:
447
This is easier to do via a resident script (0 sleep time).
Single script can be used for multiple timers by adding more entries to the timers table. The script uses current dimmer control value to determine what level to set, only values set by other sources (not the script itself) are used. There are two points - high and low, if the current value is less than low then low value is used, otherwise high value is used. The status value cannot be used here because it's impossible to tell who change the value that caused the status update.
An alternative solution is to create a day/night object to have two different sets of values for movement/no movement.
Code: if not client then
timers = {
{
input = '1/1/1', -- binary PIR status
output = '1/1/3', -- dimmer control (0..100%)
onvaluehigh = 90, -- high output value in %
onvaluelow = 30, -- low output value in %
timeout = 60, -- in seconds
}
}
function setinputvalue(timer, event)
local value = busdatatype.decode(event.datahex, dt.bool)
if not value then
return
end
if timer.outvalue < timer.onvaluelow then
value = timer.onvaluelow
elseif timer.outvalue < timer.onvaluehigh then
value = timer.onvaluehigh
else
value = nil
end
if not timer.ticks and value then
grp.write(timer.output, value, dt.scale)
end
timer.ticks = timer.timeout
end
function setoutputvalue(timer, event)
timer.outvalue = busdatatype.decode(event.datahex, dt.scale)
timer.ticks = nil -- stop timer
end
for _, timer in ipairs(timers) do
timer.outvalue = grp.getvalue(timer.output)
end
sender = 'tm'
grp.sender = sender
client = require('localbus').new(0.1)
client:sethandler('groupwrite', function(event)
if event.sender == sender then
return
end
for _, timer in ipairs(timers) do
if timer.input == event.dst then
setinputvalue(timer, event)
elseif timer.output == event.dst then
setoutputvalue(timer, event)
end
end
end)
end
client:loop(1)
for _, timer in ipairs(timers) do
if timer.ticks then
timer.ticks = timer.ticks - 1
if timer.ticks == 0 then
grp.write(timer.output, timer.outvalue, dt.scale)
timer.ticks = nil
end
end
end
Posts: 22
Threads: 4
Joined: Nov 2019
Reputation:
0
This script is more complex than I can make myself. Very cool to see that you made this one so for me. Thank you, thank you!
I have adopted the script as resident script with 0 sleep time.
I also deleted my own scripts.
I filled in the table as follows:
{
input = '9/0/1', -- binary PIR status
output = '1/1/7', -- dimmer control (0..100%)
onvaluehigh = 90, -- high output value in %
onvaluelow = 10, -- low output value in %
timeout = 5, -- in seconds
}
And I also tried filling in the status object 3/1/7 as output instead of 1/1/7.
After two weeks, I tried one more time of all. Sometimes you then suddenly see what is going wrong. Unfortunately, I am not able to get this script to work.
Can you give any advice...?
Posts: 7775
Threads: 42
Joined: Jun 2015
Reputation:
447
Post your full script listing. Also enable logging for mapped object and see if they change values. Check Error logs as well.
Posts: 22
Threads: 4
Joined: Nov 2019
Reputation:
0
(09.06.2022, 15:33)admin Wrote: Post your full script listing. Also enable logging for mapped object and see if they change values. Check Error logs as well.
Thanks. Here is my answer:
Sorry for not noticing the error log. There are errors:
---
Resident script:19: attempt to compare nil with number
stack traceback:
Resident script:19: in function 'setinputvalue'
Resident script:54: in function <Resident script:47>
Library localbus: in function ''
Library localbus: in function ''
Library localbus: in function 'loop'
---
'1/1/7' is the object of the dimming value.
I have logged 1/1/7. No logs registered.
Code: if not client then
timers = {
{
input = '9/0/1', -- binary PIR status
output = '1/1/7', -- dimmer control (0..100%)
onvaluehigh = 90, -- high output value in %
onvaluelow = 10, -- low output value in %
timeout = 5, -- in seconds
}
}
function setinputvalue(timer, event)
local value = busdatatype.decode(event.datahex, dt.bool)
if not value then
return
end
if timer.value < timer.onvaluelow then
value = timer.onvaluelow
elseif timer.outvalue < timer.onvaluehigh then
value = timer.onvaluehigh
else
value = nil
end
if not timer.ticks and value then
grp.write(timer.output, value, dt.scale)
end
timer.ticks = timer.timeout
end
function setoutputvalue(timer, event)
timer.outvalue = busdatatype.decode(event.datahex, dt.scale)
timer.ticks = nil -- stop timer
end
for _, timer in ipairs(timers) do
timer.outvalue = grp.getvalue(timer.output)
end
sender = 'tm'
grp.sender = sender
client = require('localbus').new(0.1)
client:sethandler('groupwrite', function(event)
if event.sender == sender then
return
end
for _, timer in ipairs(timers) do
if timer.input == event.dst then
setinputvalue(timer, event)
elseif timer.output == event.dst then
setoutputvalue(timer, event)
end
end
end)
end
client:loop(1)
for _, timer in ipairs(timers) do
if timer.ticks then
timer.ticks = timer.ticks - 1
if timer.ticks == 0 then
grp.write(timer.output, timer.outvalue, dt.scale)
timer.ticks = nil
end
end
end
Posts: 7775
Threads: 42
Joined: Jun 2015
Reputation:
447
Line 19 should have timer.outvalue instead of timer.value:
Code: if timer.outvalue < timer.onvaluelow then
Posts: 22
Threads: 4
Joined: Nov 2019
Reputation:
0
(13.06.2022, 07:00)admin Wrote: Line 19 should have timer.outvalue instead of timer.value:
Code: if timer.outvalue < timer.onvaluelow then
Thanks for reaction. I have changed this, but error is the same:
Code: if not client then
timers = {
{
input = '9/0/1', -- binary PIR status
output = '1/1/7', -- dimmer control (0..100%)
onvaluehigh = 90, -- high output value in %
onvaluelow = 10, -- low output value in %
timeout = 5, -- in seconds
}
}
function setinputvalue(timer, event)
local value = busdatatype.decode(event.datahex, dt.bool)
if not value then
return
end
if timer.outvalue < timer.onvaluelow then
value = timer.onvaluelow
elseif timer.outvalue < timer.onvaluehigh then
value = timer.onvaluehigh
else
value = nil
end
if not timer.ticks and value then
grp.write(timer.output, value, dt.scale)
end
timer.ticks = timer.timeout
end
function setoutputvalue(timer, event)
timer.outvalue = busdatatype.decode(event.datahex, dt.scale)
timer.ticks = nil -- stop timer
end
for _, timer in ipairs(timers) do
timer.outvalue = grp.getvalue(timer.output)
end
sender = 'tm'
grp.sender = sender
client = require('localbus').new(0.1)
client:sethandler('groupwrite', function(event)
if event.sender == sender then
return
end
for _, timer in ipairs(timers) do
if timer.input == event.dst then
setinputvalue(timer, event)
elseif timer.output == event.dst then
setoutputvalue(timer, event)
end
end
end)
end
client:loop(1)
for _, timer in ipairs(timers) do
if timer.ticks then
timer.ticks = timer.ticks - 1
if timer.ticks == 0 then
grp.write(timer.output, timer.outvalue, dt.scale)
timer.ticks = nil
end
end
end
Resident script:19: attempt to compare nil with number
stack traceback:
Resident script:19: in function 'setinputvalue'
Resident script:54: in function <Resident script:47>
Library localbus: in function ''
Library localbus: in function ''
Libbrarary localbus: in function 'loop'
Posts: 7775
Threads: 42
Joined: Jun 2015
Reputation:
447
The same script works for me. Does 9/0/1 exist?
I've added some logging, check what you get in the Logs tab:
Code: if not client then
timers = {
{
input = '9/0/1', -- binary PIR status
output = '1/1/7', -- dimmer control (0..100%)
onvaluehigh = 90, -- high output value in %
onvaluelow = 10, -- low output value in %
timeout = 5, -- in seconds
}
}
function setinputvalue(timer, event)
local value = busdatatype.decode(event.datahex, dt.bool)
if not value then
return
end
log('pir trigger', timer.outvalue)
if timer.outvalue < timer.onvaluelow then
value = timer.onvaluelow
elseif timer.outvalue < timer.onvaluehigh then
value = timer.onvaluehigh
else
value = nil
end
if not timer.ticks and value then
grp.write(timer.output, value, dt.scale)
end
timer.ticks = timer.timeout
end
function setoutputvalue(timer, event)
timer.outvalue = busdatatype.decode(event.datahex, dt.scale)
timer.ticks = nil -- stop timer
log('output change', timer.outvalue)
end
for _, timer in ipairs(timers) do
timer.outvalue = grp.getvalue(timer.output)
log('timer init', timer.outvalue)
end
sender = 'tm'
grp.sender = sender
client = require('localbus').new(0.1)
client:sethandler('groupwrite', function(event)
if event.sender == sender then
return
end
for _, timer in ipairs(timers) do
if timer.input == event.dst then
setinputvalue(timer, event)
elseif timer.output == event.dst then
setoutputvalue(timer, event)
end
end
end)
end
client:loop(1)
for _, timer in ipairs(timers) do
if timer.ticks then
timer.ticks = timer.ticks - 1
if timer.ticks == 0 then
log('timer stop', timer.outvalue)
grp.write(timer.output, timer.outvalue, dt.scale)
timer.ticks = nil
end
end
end
Posts: 22
Threads: 4
Joined: Nov 2019
Reputation:
0
I modified the code and it still did not work. I searched for a while, until I found the ultimate solution: reboot the device. After that, the error messages were immediately gone, and the script works. I can't explain it, but fortunately it's solved. Thank you, thank you!
I'm still running into a problem, and I also have a question about applying this script to other lamps inside and outside the house:
Problem:
If the script is running and has turned the lamp up when there is movement, and then within the set time period the lamp is turned off (for example, because we are going to bed), then the script turns the lamp - after the set time has expired - back on to its original dimming status. Unfortunately, this was not the intention. The lamp should then remain off. Is there a solution for this?
Question:
Is it possible to indicate in the script for each PIR via a separate object whether it is active or not?
And is it possible to include a PIR twice in the timers table. For example, an outdoor lamp in the backyard in winter has a different behaviour than in summer?
Posts: 7775
Threads: 42
Joined: Jun 2015
Reputation:
447
A separate timer on/off object can be added as well as another on/off object to monitor manual lamp operation. What should happen when the lamp is turned on manually? Which level should the script use?
Posts: 22
Threads: 4
Joined: Nov 2019
Reputation:
0
17.06.2022, 17:01
(This post was last modified: 17.06.2022, 17:22 by Dirk79.)
(17.06.2022, 14:18)admin Wrote: A separate timer on/off object can be added as well as another on/off object to monitor manual lamp operation. What should happen when the lamp is turned on manually? Which level should the script use?
Super that this is possible!
Preferably, the lamp returns to its last initial position. That is, the position the lamp was in the last time, before movement was detected.
E.g. the lamp is on 35%, it is turned to 90% by the script and is then turned off manually or by another script or a scene. The next time the lamp is turned on manually (or by a scene), it should start at 35%.
But if that results in a very complex script, then a fixed value, e.g. 30%, is also good.
Thanks.
Posts: 7775
Threads: 42
Joined: Jun 2015
Reputation:
447
Updated version with an optional timer on/off object and status monitoring. For this to work the dimmer must have a status output active and should report the status as soon as possible (some dimmers have an option to report status when only after a transition). When the script writes its output value it will ignore the status report for 1 second. This can be lowered (line 53) to prevent possible issues when a manual control is performed at the same moment as the scripted control.
Code: if not client then
timers = {
{
input = '1/1/1', -- binary PIR status
enable = '1/1/2', -- enable timer on/off
output = '1/1/3', -- dimmer control (0..100%)
status = '1/1/4', -- dimmer status (0..100%)
onvaluehigh = 90, -- high output value in %
onvaluelow = 10, -- low output value in %
timeout = 5, -- in seconds
}
}
function setoutputvalue(timer, value)
timer.ignoresec, timer.ignoreusec = os.microtime()
grp.write(timer.output, value, dt.scale)
end
function settimerstate(timer, event)
timer.enabled = busdatatype.decode(event.datahex, dt.bool)
timer.ticks = nil
log('timer enabled', timer.enabled)
end
function setinputvalue(timer, event)
local value = busdatatype.decode(event.datahex, dt.bool)
if not value or not timer.enabled then
return
end
log('pir trigger', timer.statvalue)
if timer.statvalue < timer.onvaluelow then
value = timer.onvaluelow
elseif timer.statvalue < timer.onvaluehigh then
value = timer.onvaluehigh
else
value = nil
end
if not timer.ticks and value then
setoutputvalue(timer, value)
end
timer.ticks = timer.timeout
end
function setstatusvalue(timer, event)
if timer.ignoresec then
local delta = os.udifftime(timer.ignoresec, timer.ignoreusec)
if delta >= 0 and delta <= 1 then
return
end
timer.ignoresec = nil
end
if timer.enabled then
timer.statvalue = busdatatype.decode(event.datahex, dt.scale)
timer.ticks = nil -- stop timer
log('output change', timer.statvalue)
end
end
for _, timer in ipairs(timers) do
timer.statvalue = grp.getvalue(timer.status) or 0
if timer.enable then
timer.enabled = grp.getvalue(timer.enable)
else
timer.enabled = true
end
log('timer init', timer.statvalue, timer.enabled)
end
sender = 'tm'
grp.sender = sender
client = require('localbus').new(0.1)
client:sethandler('groupwrite', function(event)
if event.sender == sender then
return
end
for _, timer in ipairs(timers) do
if event.dst == timer.enable then
settimerstate(timer, event)
elseif event.dst == timer.switch then
setswitchvalue(timer, event)
elseif event.dst == timer.input then
setinputvalue(timer, event)
elseif event.dst == timer.status then
setstatusvalue(timer, event)
end
end
end)
end
client:loop(1)
for _, timer in ipairs(timers) do
if timer.ticks then
timer.ticks = timer.ticks - 1
if timer.ticks == 0 then
log('timer stop', timer.statvalue)
setoutputvalue(timer, timer.statvalue)
timer.ticks = nil
end
end
end
Posts: 22
Threads: 4
Joined: Nov 2019
Reputation:
0
(22.06.2022, 10:29)admin Wrote: Updated version with an optional timer on/off object and status monitoring. For this to work the dimmer must have a status output active and should report the status as soon as possible (some dimmers have an option to report status when only after a transition). When the script writes its output value it will ignore the status report for 1 second. This can be lowered (line 53) to prevent possible issues when a manual control is performed at the same moment as the scripted control.
Code: if not client then
timers = {
{
input = '1/1/1', -- binary PIR status
enable = '1/1/2', -- enable timer on/off
output = '1/1/3', -- dimmer control (0..100%)
status = '1/1/4', -- dimmer status (0..100%)
onvaluehigh = 90, -- high output value in %
onvaluelow = 10, -- low output value in %
timeout = 5, -- in seconds
}
}
function setoutputvalue(timer, value)
timer.ignoresec, timer.ignoreusec = os.microtime()
grp.write(timer.output, value, dt.scale)
end
function settimerstate(timer, event)
timer.enabled = busdatatype.decode(event.datahex, dt.bool)
timer.ticks = nil
log('timer enabled', timer.enabled)
end
function setinputvalue(timer, event)
local value = busdatatype.decode(event.datahex, dt.bool)
if not value or not timer.enabled then
return
end
log('pir trigger', timer.statvalue)
if timer.statvalue < timer.onvaluelow then
value = timer.onvaluelow
elseif timer.statvalue < timer.onvaluehigh then
value = timer.onvaluehigh
else
value = nil
end
if not timer.ticks and value then
setoutputvalue(timer, value)
end
timer.ticks = timer.timeout
end
function setstatusvalue(timer, event)
if timer.ignoresec then
local delta = os.udifftime(timer.ignoresec, timer.ignoreusec)
if delta >= 0 and delta <= 1 then
return
end
timer.ignoresec = nil
end
if timer.enabled then
timer.statvalue = busdatatype.decode(event.datahex, dt.scale)
timer.ticks = nil -- stop timer
log('output change', timer.statvalue)
end
end
for _, timer in ipairs(timers) do
timer.statvalue = grp.getvalue(timer.status) or 0
if timer.enable then
timer.enabled = grp.getvalue(timer.enable)
else
timer.enabled = true
end
log('timer init', timer.statvalue, timer.enabled)
end
sender = 'tm'
grp.sender = sender
client = require('localbus').new(0.1)
client:sethandler('groupwrite', function(event)
if event.sender == sender then
return
end
for _, timer in ipairs(timers) do
if event.dst == timer.enable then
settimerstate(timer, event)
elseif event.dst == timer.switch then
setswitchvalue(timer, event)
elseif event.dst == timer.input then
setinputvalue(timer, event)
elseif event.dst == timer.status then
setstatusvalue(timer, event)
end
end
end)
end
client:loop(1)
for _, timer in ipairs(timers) do
if timer.ticks then
timer.ticks = timer.ticks - 1
if timer.ticks == 0 then
log('timer stop', timer.statvalue)
setoutputvalue(timer, timer.statvalue)
timer.ticks = nil
end
end
end
Thank you again!
With this message, I give an update of the status:
I have been using this modified script for some time now. It works far better, but I still cannot get it to work 100% correctly.
I would have liked to explain what is going wrong, but it is not easy since the behaviour of the script changes .
What have I experienced:
Some days the script does not work at all (after restarting, this is then solved).
My family told me that the script also worked the other way around once. So that the lamp went on, while it should have stayed off.
Some additional information:
As enabler I used the status object of the lamp itself. So only if the lamp is already on, it must be made louder.
I have also noticed that the numbers behind CPU/IO at the bottom sometimes turn red for a while. I don't know if that is relevant. I'm reporting it just to be sure.
Additional challenge: Because it is currently light outside for so long, it is also more difficult to see whether the script is working as desired. It is only when it is dark outside that it is noticeable when the lamp is turned up and then down again.
I'm going to gain more experience and as soon as I can describe better what exactly happens, I'll let you know.
Posts: 7775
Threads: 42
Joined: Jun 2015
Reputation:
447
Keep logs in the script enabled and also enable logging for all objects that are used by the script. Then you can find why it's not always working as intended.
Posts: 22
Threads: 4
Joined: Nov 2019
Reputation:
0
10.12.2022, 13:14
(This post was last modified: 10.12.2022, 13:15 by Dirk79.)
It took a while since my last message. It is dark much earlier now, I have more logs and I can better see when things go wrong.
Every day the script starts as desired. It starts at 30%, but it disrupts every day. Then it will hang on the brighter setting. I have a series of logs below where you can see the sudden change at 09.12.2022 20:30:55. Hopefully this is enough information to understand the problem. If not, I'd like to share more :-).
09.12.2022 23:57:23 Lights temporary brighter on PIR *arg:1* string: timer enabled * arg: 2 * bool: false
09.12.2022 23:31:12 Lights temporary brighter on PIR *arg:1* string: timer stop * arg: 2 * number: 90
09.12.2022 23:31:08 Lights temporary brighter on PIR *arg:1* string: pir trigger * arg: 2 * number: 90
09.12.2022 23:30:38 Lights temporary brighter on PIR *arg:1* string: timer stop * arg: 2 * number: 90
09.12.2022 23:30:33 Lights temporary brighter on PIR *arg:1* string: pir trigger * arg: 2 * number: 90
09.12.2022 23:00:09 Lights temporary brighter on PIR *arg:1* string: timer stop * arg: 2 * number: 90
09.12.2022 23:00:04 Lights temporary brighter on PIR *arg:1* string: pir trigger * arg: 2 * number: 90
09.12.2022 23:00:00 Lights temporary brighter on PIR *arg:1* string: pir trigger * arg: 2 * number: 90
09.12.2022 21:35:09 Lights temporary brighter on PIR *arg:1* string: timer stop * arg: 2 * number: 90
09.12.2022 21:35:03 Lights temporary brighter on PIR *arg:1* string: pir trigger * arg: 2 * number: 90
09.12.2022 21:34:12 Lights temporary brighter on PIR *arg:1* string: timer stop * arg: 2 * number: 90
09.12.2022 21:34:08 Lights temporary brighter on PIR *arg:1* string: pir trigger * arg: 2 * number: 90
09.12.2022 21:34:04 Lights temporary brighter on PIR *arg:1* string: pir trigger * arg: 2 * number: 90
09.12.2022 21:33:15 Lights temporary brighter on PIR *arg:1* string: timer stop * arg: 2 * number: 90
09.12.2022 21:33:11 Lights temporary brighter on PIR *arg:1* string: pir trigger * arg: 2 * number: 90
09.12.2022 21:32:31 Lights temporary brighter on PIR *arg:1* string: timer stop * arg: 2 * number: 90
09.12.2022 21:32:27 Lights temporary brighter on PIR *arg:1* string: pir trigger * arg: 2 * number: 90
09.12.2022 21:32:21 Lights temporary brighter on PIR *arg:1* string: timer stop * arg: 2 * number: 90
09.12.2022 21:32:16 Lights temporary brighter on PIR *arg:1* string: pir trigger * arg: 2 * number: 90
09.12.2022 21:30:03 Lights temporary brighter on PIR *arg:1* string: timer stop * arg: 2 * number: 90
09.12.2022 21:29:58 Lights temporary brighter on PIR *arg:1* string: pir trigger * arg: 2 * number: 90
09.12.2022 21:25:42 Lights temporary brighter on PIR *arg:1* string: timer stop * arg: 2 * number: 90
09.12.2022 21:25:37 Lights temporary brighter on PIR *arg:1* string: pir trigger * arg: 2 * number: 90
09.12.2022 20:52:51 Lights temporary brighter on PIR *arg:1* string: timer stop * arg: 2 * number: 90
09.12.2022 20:52:46 Lights temporary brighter on PIR *arg:1* string: pir trigger * arg: 2 * number: 90
09.12.2022 20:42:57 Lights temporary brighter on PIR *arg:1* string: timer stop * arg: 2 * number: 90
09.12.2022 20:42:53 Lights temporary brighter on PIR *arg:1* string: pir trigger * arg: 2 * number: 90
09.12.2022 20:42:15 Lights temporary brighter on PIR *arg:1* string: timer stop * arg: 2 * number: 90
09.12.2022 20:42:10 Lights temporary brighter on PIR *arg:1* string: pir trigger * arg: 2 * number: 90
09.12.2022 20:36:23 Lights temporary brighter on PIR *arg:1* string: timer stop * arg: 2 * number: 90
09.12.2022 20:36:18 Lights temporary brighter on PIR *arg:1* string: pir trigger * arg: 2 * number: 90
09.12.2022 20:35:36 Lights temporary brighter on PIR *arg:1* string: timer stop * arg: 2 * number: 90
09.12.2022 20:35:32 Lights temporary brighter on PIR *arg:1* string: pir trigger * arg: 2 * number: 90
09.12.2022 20:30:55 Lights temporary brighter on PIR *arg:1* string: output change * arg: 2 * number: 90
09.12.2022 20:30:51 Lights temporary brighter on PIR *arg:1* string: pir trigger * arg: 2 * number: 30
09.12.2022 20:30:49 Lights temporary brighter on PIR *arg:1* string: timer stop * arg: 2 * number: 30
09.12.2022 20:30:44 Lights temporary brighter on PIR *arg:1* string: pir trigger * arg: 2 * number: 30
09.12.2022 19:25:52 Lights temporary brighter on PIR *arg:1* string: timer stop * arg: 2 * number: 30
09.12.2022 19:25:48 Lights temporary brighter on PIR *arg:1* string: pir trigger * arg: 2 * number: 30
09.12.2022 19:25:14 Lights temporary brighter on PIR *arg:1* string: timer stop * arg: 2 * number: 30
09.12.2022 19:25:09 Lights temporary brighter on PIR *arg:1* string: pir trigger * arg: 2 * number: 30
09.12.2022 19:22:10 Lights temporary brighter on PIR *arg:1* string: timer stop * arg: 2 * number: 30
09.12.2022 19:22:05 Lights temporary brighter on PIR *arg:1* string: pir trigger * arg: 2 * number: 30
09.12.2022 18:54:34 Lights temporary brighter on PIR *arg:1* string: timer stop * arg: 2 * number: 30
09.12.2022 18:54:29 Lights temporary brighter on PIR *arg:1* string: pir trigger * arg: 2 * number: 30
09.12.2022 18:53:16 Lights temporary brighter on PIR *arg:1* string: timer stop * arg: 2 * number: 30
09.12.2022 18:53:11 Lights temporary brighter on PIR *arg:1* string: pir trigger * arg: 2 * number: 30
09.12.2022 17:56:05 Lights temporary brighter on PIR *arg:1* string: timer stop * arg: 2 * number: 30
09.12.2022 18:05:40 Lights temporary brighter on PIR *arg:1* string: pir trigger * arg: 2 * number: 30
09.12.2022 18:05:45 Lights temporary brighter on PIR *arg:1* string: timer stop * arg: 2 * number: 30
09.12.2022 18:06:22 Lights temporary brighter on PIR *arg:1* string: pir trigger * arg: 2 * number: 30
09.12.2022 18:06:27 Lights temporary brighter on PIR *arg:1* string: timer stop * arg: 2 * number: 30
Posts: 7775
Threads: 42
Joined: Jun 2015
Reputation:
447
The status change most likely comes from a manual control. With the current logic it won't go back to low level until the light is manually switched off.
Posts: 22
Threads: 4
Joined: Nov 2019
Reputation:
0
(13.12.2022, 11:51)admin Wrote: The status change most likely comes from a manual control. With the current logic it won't go back to low level until the light is manually switched off.
Thank you again!
I understand this thought, but I would still like to rule it out. To prove this, I first did a test.
To my knowledge there is no other action that puts the light at exactly 90%.
To test this, I set the value in the program to 85%. I had to restart the system for this to take effect. After this restart, the error remains the same, only the lamp is then set to 85% instead of 90%. I didn't change anything else, so I think I've confirmed that this script itself sets it to 85%.
Every day the lamp starts at 30% according to a different script.
I would like to know if this test is sufficient to show that the script itself chooses the higher value as the new setting, and if there is anything else I can try?
Posts: 22
Threads: 4
Joined: Nov 2019
Reputation:
0
Dear admin,
I have done some additional testing. Hopefully the additional information can help to solve the problem.
During my last messages, the timeout period in the script was 5 seconds. I ran several tests with different timeout periods.
The frequency at which the motion detector transmits a notification is not constant. If you just walk past it, only one trigger will come. If you stay near the motion detector, more triggers will follow each other. The interval between the triggers is usually approx. 5 seconds, but is occasionally faster (2 seconds seen as fastest) or longer. So therefore I ran several tests:
a) At the 5-second timeout, the lamp went brighter for a moment and also went softer again. Every time the PIR transmits a new motion trigger the lamp went back. Almost every night, the script went wrong. Not immediately, but often when there was a lot of 'traffic'. Then the lamp stayed on the higher setting.
b) Then I ran the script on 5-minute timeout for several days. The script ran into error almost immediately every day.
c) Then I ran the lamp on 1 second timeout for several days. When motion detection is detected, the lamp turns on slightly brighter very briefly (maximum setting is not reached) and immediately goes back down. However, the script does not run into error. Not once did the script stay on the high setting.
So my conclusion is that the script is disrupted when a new motion notification comes in at the moment the lamp is already burning brighter. Can this be solved by adding a rule to the script or the like?
I am not saying the script is incorrect. Perhaps it is because of my equipment, but clearly it is not working properly. It would be nice if a solution is available for this, because then my problem would be solved .
Thanks!
|