SpaceLogic KNX Forum
Schneider Electric SpaceLogic KNX forum to get support and share knowledge including selection, installation and troubleshooting for spaceLYnk, Wiser for KNX, eConfigure KNX, SpaceLogic KNX Hybrid module and other topics.
Posted: 2017-04-20 03:31 AM . Last Modified: 2024-07-14 11:53 PM
Link copied. Please paste this link to share this article on your social media post.
Dear all,
is anyone of you aware of a HL or SL solution, which allows a presence
simulation without using a Schedulers?
A command should make the HL s start recording the group addresses for 2 weeks.
The recording should be played for 2 weeks, again triggered by a command.
Many Thanks
Benjamin
Link copied. Please paste this link to share this article on your social media post.
Hi Benjamin.
Here is the script for presence simulation. But it only records 1 day or 1 week or record always.
Br
Martin Rausch
----Create EVENT-BASED SCRIPT---------------------
-- Presence Simulation Module Version 2.0 - Recording part
-- Created by Erwin van der Zwart
-- ********** SET PARAMETERS ***********
-- Set address for selecting modus of Simulation Module (0 = Recorder off, 1 = Record Today, 2 = Record Sunday, 3 = Record Monday, 4 = Record Tuesday, 5 = Record Wednesday, 6 = Record Thursday, 7 = Record Friday , 8 = Record Saturday, 9 = Record Midweek, 10 = Record Weekend, 11 = Record Full Week from Activation, 12 = Record Full Week from Day 1, 13 = Record Always, 14 = Record to Play Direct, 15 = Player Active, 16 = Delete all recorded data)
Address_Modus = '1/1/125' -- Byte object ! -- Set as byte address with custom text and min/max 0 to 14 and make a separate button for value 15 with pincode (delete all recordings)
-- Set address for play and stop
Address_Play_Stop = '1/1/126' -- Bit object !
-- Set address for delete recordings
Address_Delete = '1/1/127' -- Bit object !
-- Set Conformation LED play / stop (Optional)
Address_Play_Stop_Feedback = '1/1/128' -- Bit object !
-- Set Conformation LED delete (Optional)
Address_Delete_Feedback = '1/1/129' -- Bit object !
-- Set TAG used for selecting objects to be record
Recording_Tag = 'Simulatie'
-- Set scriptname for playing recorded objects and to disable/exit this recording (to avoid loop recording)
Player_Script_Name = 'Simulatie Speler'
-- Set name for storage for objects to be recorded
Storage_Name = 'STSIMULATION'
-- ********** END PARAMETERS ***********
-- Check if player is active
Current_Start_Stop_Value = grp.getvalue(Address_Play_Stop)
if Current_Start_Stop_Value == true then
-- Turn on feedback LED
-- Get start / stop feedback value
A_P_S = grp.getvalue(Address_Play_Stop_Feedback)
if A_P_S == false then
-- Enable start / stop feedback LED
grp.update(Address_Play_Stop_Feedback, true)
end
-- Check if command is from modus selection
-- Action on Selecting Modus
if event.dst == Address_Modus then
-- Get current script status
Script_Status = script.status(Player_Script_Name)
if Script_Status == true then
-- Disable player script
script.disable(Player_Script_Name)
end
-- Turn off feedback LED
-- Get start / stop feedback value
A_P_S = grp.getvalue(Address_Play_Stop_Feedback)
if A_P_S == true then
-- Disable start / stop feedback LED
grp.update(Address_Play_Stop_Feedback, false)
end
-- Exit Script
return
end
-- Get Object information
objectinfo = grp.find(event.dst)
-- Get simulation module modus value
modus = grp.getvalue(Address_Modus)
-- Check if modus value is between allowed range
if modus >= 1 and modus <= 16 then
-- Do nothing, move on with scipt
else
-- Turn off feedback LED
-- Get start / stop feedback value
A_P_S = grp.getvalue(Address_Play_Stop_Feedback)
if A_P_S == true then
-- Disable start / stop feedback LED
grp.update(Address_Play_Stop_Feedback, false)
end
-- Exit script (also when modus = 0 for recorder off)
return
end
-- Set Player Active
if modus == 15 then
-- Get status of player script
status = script.status(Player_Script_Name)
if status == false then
-- Enable player script
script.enable(Player_Script_Name)
end
-- Exit script
return
end
-- Delete all recorded data
if modus == 16 then
-- Delete all recorded data from storage
storage.set(Storage_Name, nil)
alert('All recorded simulation data is deleted')
-- Turn off feedback LED
-- Get start / stop feedback value
A_P_S = grp.getvalue(Address_Play_Stop_Feedback)
if A_P_S == true then
-- Disable start / stop feedback LED
grp.update(Address_Play_Stop_Feedback, false)
end
-- Exit script
return
end
-- Make sure events from Address_Modus are not recorded
if event.dst == Address_Modus then
-- Turn off feedback LED
-- Get start / stop feedback value
A_P_S = grp.getvalue(Address_Play_Stop_Feedback)
if A_P_S == true then
-- Disable start / stop feedback LED
grp.update(Address_Play_Stop_Feedback, false)
end
-- Exit script
return
end
-- Make sure events are not recorded while recorder is inactive, player is active or deletion mode is selected
if modus == 0 or modus == 15 or modus == 16 then
-- Exit script
return
end
-- When modus is 1 to 14 then this will be executed:
-- Get object last change timestamp to determine recording day
objecttimestamp = objectinfo.updatetime
objecttimetable = os.date("*t", objecttimestamp)
-- Get Modus last change timestamp to determine recording day
modusinfo = grp.find(Address_Modus)
modustimestamp = modusinfo.updatetime
modustimetable = os.date("*t", modustimestamp)
if modus == 1 then -- Record Today
if objecttimetable.yday == modustimetable.yday and objecttimetable.year == modustimetable.year then
-- Continue Script
else
-- Exit Script
return
end
elseif modus == 2 then -- Record Sonday
if objecttimetable.wday == 1 and (objecttimestamp - modustimestamp) < 604800 then
-- Continue Script
else
-- Exit Script
return
end
elseif modus == 3 then -- Record Monday
if objecttimetable.wday == 2 and (objecttimestamp - modustimestamp) < 604800 then
-- Continue Script
else
-- Exit Script
return
end
elseif modus == 4 then -- Record Tuesday
if objecttimetable.wday == 3 and (objecttimestamp - modustimestamp) < 604800 then
-- Continue Script
else
-- Exit Script
return
end
elseif modus == 5 then -- Record Wednesday
if objecttimetable.wday == 4 and (objecttimestamp - modustimestamp) < 604800 then
-- Continue Script
else
-- Exit Script
return
end
elseif modus == 6 then -- Record Thursday
if objecttimetable.wday == 5 and (objecttimestamp - modustimestamp) < 604800 then
-- Continue Script
else
-- Exit Script
return
end
elseif modus == 7 then -- Record Friday
if objecttimetable.wday == 6 and (objecttimestamp - modustimestamp) < 604800 then
-- Continue Script
else
-- Exit Script
return
end
elseif modus == 8 then -- Record Saturday
if objecttimetable.wday == 7 and (objecttimestamp - modustimestamp) < 604800 then
-- Continue Script
else
-- Exit Script
return
end
elseif modus == 9 then -- Record Midweek
if objecttimetable.wday == 2 or objecttimetable.wday == 3 or objecttimetable.wday == 4 or objecttimetable.wday == 5 or objecttimetable.wday == 6 and (objecttimestamp - modustimestamp) < 604800 then
-- Continue Script
else
-- Exit Script
return
end
elseif modus == 10 then -- Record Weekend
if objecttimetable.wday == 1 or objecttimetable.wday == 7 and (objecttimestamp - modustimestamp) < 604800 then
-- Continue Script
else
-- Exit Script
return
end
elseif modus == 11 then -- Record Full Week from Activation
if (objecttimestamp - modustimestamp) < 604800 then
-- Continue Script
else
-- Exit Script
return
end
elseif modus == 12 then -- Record Full Week from Day 1
if ((modustimetable.yday - modustimetable.wday) + 7) == (updatetimetable.yday - updatetimetable.wday) and (objecttimestamp - modustimestamp) < 604800 then
-- Continue Script
else
-- Exit Script
return
end
elseif modus == 13 or modus == 14 then -- Record Alway
-- Continue Script
end
-- Get previous data from storage if available
Storage_Data = storage.get(Storage_Name)
-- Check if storagedata is available
if Storage_Data == nil then
-- Create new data table
Storage_Data = {}
table.insert(Storage_Data, {updatetime = objectinfo.updatetime, address = objectinfo.address, value = objectinfo.value, recordmodus = modus, lastplayed = os.time(), timelap = (objectinfo.updatetime - modusinfo.updatetime)})
else
-- Loop through array and clear to all found items older then selected scope or from other modus in the recorded values
for index, StorageData in pairs(Storage_Data) do
-- Check value before write (if enabled)
if StorageData.recordtime == nil then
-- Do nothing
else
if (os.time() - StorageData.recordtime) > 604800 or StorageData.recordmodus ~= modus then
-- Delete item
Storage_Data[index]=nil
end
end
end
-- Add data to excisting data table
table.insert(Storage_Data, {updatetime = objectinfo.updatetime, address = objectinfo.address, value = objectinfo.value, recordmodus = modus, lastplayed = os.time(), timelap = (objectinfo.updatetime - Storage_Data[#Storage_Data].updatetime)})
end
-- Write new data back to storage
storage.set(Storage_Name, Storage_Data)
log (Storage_Data)
else
-- Get current script status
Script_Status = script.status(Player_Script_Name)
if Script_Status == true then
-- Disable player script
script.disable(Player_Script_Name)
end
-- Turn off feedback LED
-- Get start / stop feedback value
A_P_S = grp.getvalue(Address_Play_Stop_Feedback)
if A_P_S == true then
-- Disable start / stop feedback LED
grp.update(Address_Play_Stop_Feedback, false)
end
end
-------CREATE RESIDENTIAL SCRIPT--------------
-- Simulation Module Version 2.0 - Player Part
-- Created by Erwin van der Zwart
-- ********** SET PARAMETERS ***********
-- Set storage name for recorded objects
Storage_Name = 'STSIMULATION'
-- Check object if object value is changed before write (same value = no write)
Check_Object_Changed = false
-- Set random value in seconds to make switching time not exactly the same time as recording time so you won't see its automaticly send every day the same time.
Sec_Random = 1800 -- makes bandwidth of 30 minutes when recording will be played, set to 0 will disable the random function and objects will be played on same time as recording.
-- ********** END PARAMETERS ***********
-- Get data from storage if available
Storage_Data = storage.get(Storage_Name)
-- Set Data table changed to false (save data only when changes are detected)
Data_Table_Changed = false
-- Check if storagedata is available
if Storage_Data == nil then
-- Exit Script
return
else
-- Sort table by updatetime
table.sort(Storage_Data, function(first,last) return first.updatetime < last.updatetime end)
-- Set current time as timestamp for calculation
timestamp = os.time()
-- Set counter to 0
counter = 0
-- Loop through array and write to all found addresses in this recording the values
for index, StorageData in ipairs(Storage_Data) do
::ObjectStart::
-- Create random value to play object not exactly on same time but in a scope of 30 minutes from that time.
random = math.random(0, Sec_Random)
-- Create table from current time to get wday and yday
currenttimetable = os.date("*t", os.time())
-- Create table from lastplayed to get wday and yday
lastplayedtable = os.date("*t", StorageData.lastplayed)
-- Check if recordmodus is available
if StorageData.recordmodus == nil then
-- Do nothing, move to next object because this object has no modus info.
counter = counter + StorageData.timelap
goto NextObject
else
modus = StorageData.recordmodus
end
-- Check if weekday matches with recording (not for modus 1 and 14)
if modus ~= 1 or modus ~= 14 then
if currenttimetable.wday == lastplayedtable.wday then
-- Day matches, move on with script
else
-- Do nothing, move to next object because this object doesn't mach day of playing.
counter = counter + StorageData.timelap
goto NextObject
end
end
-- Check value before write (if enabled)
if Check_Object_Changed == true then
-- Get current object value
value = grp.getvalue(StorageData.address)
-- Check if value is the same
if value == StorageData.value then
-- Do nothing, move to next object because this object aready is set to wanted value.
counter = counter + StorageData.timelap
goto NextObject
end
end
-- Selected actions by modus
if modus == 14 then -- Play Direct (for testing your recordings)
-- Check if this is first object from table
if index == 1 then
if (timestamp + StorageData.timelap) <= os.time() then
-- Move to write to object part
counter = counter + StorageData.timelap
else
-- Slow looping down when object does not meet requirements (only for modus 14)
os.sleep (1)
-- Try again
goto ObjectStart
end
else
if ((timestamp + StorageData.timelap) + counter) <= os.time() then
-- Move to write to object part
counter = counter + StorageData.timelap
else
-- Slow looping down when object does not meet requirements (only for modus 14)
os.sleep (1)
-- Try again
goto ObjectStart
end
end
end
-- ** Write to object part ** (all previous conditions are true)
-- Write function for modus 1 to 13 to use when conditions are true
function WritetoObject_Modus_1_to_13()
-- Calculate if object is at least 12 hrs old (to make sure it won't be played again the same day)
if StorageData.lastplayed - os.time() >= 43200 then
timedifference = os.time() - StorageData.updatetime
-- Perform modulo 86400 to clear all passed days from time difference and keep time difference < 24hrs
result = timedifference % 86400
-- Calculate seconds to complete minutes past
result = math.floor(result / 60)
-- Calculate random to complete minutes to calculate
random = math.floor(random / 60)
-- Create a random time between 30 minutes to meet condition to play
if result >= (1440 - random) then -- 1440 = 60 min * 24 hrs
-- Write address to wanted value
grp.write(StorageData.address, StorageData.value)
-- Update timestamp last played
StorageData.lastplayed = os.time()
Data_Table_Changed = true
end
end
end
-- Write function for modus 14 to use when conditions are true
function WritetoObject_Modus_14()
grp.write(StorageData.address, StorageData.value)
end
-- Determine what objects to play on recording conditions
if modus == 1 then -- Today
WritetoObject_Modus_1_to_13()
elseif modus == 2 and currenttimetable.wday == 1 then -- Sunday
WritetoObject_Modus_1_to_13()
elseif modus == 3 and currenttimetable.wday == 2 then -- Monday
WritetoObject_Modus_1_to_13()
elseif modus == 4 and currenttimetable.wday == 3 then -- Tuesday
WritetoObject_Modus_1_to_13()
elseif modus == 5 and currenttimetable.wday == 4 then -- Wednesday
WritetoObject_Modus_1_to_13()
elseif modus == 6 and currenttimetable.wday == 5 then -- Thursday
WritetoObject_Modus_1_to_13()
elseif modus == 7 and currenttimetable.wday == 6 then -- Vriday
WritetoObject_Modus_1_to_13()
elseif modus == 8 and currenttimetable.wday == 7 then -- Saterday
WritetoObject_Modus_1_to_13()
elseif modus == 9 and (currenttimetable.wday == 2 or currenttimetable.wday == 3 or currenttimetable.wday == 4 or currenttimetable.wday == 5 or currenttimetable.wday == 6) then -- Midweek
WritetoObject_Modus_1_to_13()
elseif modus == 10 and (currenttimetable.wday == 1 or currenttimetable.wday == 7) then -- Weekend
WritetoObject_Modus_1_to_13()
elseif (modus == 11 or modus == 12 or modus == 13) and currenttimetable.wday == lastplayedtable.wday then -- Full Week from Activation, Full Week from Day 1 and Always
WritetoObject_Modus_1_to_13()
elseif modus == 14 then -- Play direct
WritetoObject_Modus_14()
end
::NextObject::
end
-- Write changed table back to storage when timestamp lastplayed is changed during playing
if Data_Table_Changed == true then
-- Write new data back to storage
storage.set(Storage_Name, Storage_Data)
end
end
Link copied. Please paste this link to share this article on your social media post.
Many Thanks
Create your free account or log in to subscribe to the board - and gain access to more than 10,000+ support articles along with insights from experts and peers.