Jump to content

Welcome to Smart Home Forum by FIBARO

Dear Guest,

 

as you can notice parts of Smart Home Forum by FIBARO is not available for you. You have to register in order to view all content and post in our community. Don't worry! Registration is a simple free process that requires minimal information for you to sign up. Become a part of of Smart Home Forum by FIBARO by creating an account.

 

As a member you can:

  •     Start new topics and reply to others
  •     Follow topics and users to get email updates
  •     Get your own profile page and make new friends
  •     Send personal messages
  •     ... and learn a lot about our system!

 

Regards,

Smart Home Forum by FIBARO Team


  • 0

Smart Light


Question

Posted

Hi,

I'm using the SmartLight code from Stevenvd, but I need to have an additional motionsensor added to the code (My livingroom is too big for only one motion sensor)..

I'm still pretty novice with regards to LUA and the things I have tried didn't work..

Could anybody please help me to add another motionsensor to the below code:

--[[

%% properties

69 value

71 value

%% globals

TimeOfDay

--]]

--[[ Change - XXX value - above. One for motion sensor, one for Light sensor.

TimeOfDay global variable and lux make sure that the scene

will be triggered when you are already in the room and something changes.

Set your settings below, lights and add extra functions

This code is developed by Control Living. You can use this free of charge.

Feel free to suggest changes or contact when having problems.

Version 1.4.3

--]]

--------------------------------------------------------------------

-----------------------YOUR LIGHT SETTINGS--------------------------

--TODO: make possible for multiple motion sensors in one room

motionSensorID = 69; -- change id for your motion sensor.

LuxSensorID = 71; -- change id for your light sensor.

AutoLightsVdId = 555; -- The virtual device ID for the automatic lights timer.

--Enter the name of your Global variable. WITHOUT IT, THE SCENE DOES NOT WORK. Capital sensitive!

sleepState = "SleepState"; --Sleep globalstate variable.

timeOfDay = "TimeOfDay"; --Time of Day Global variable.

presentState = "PresentState"; --Present state Global variable.

--Enter the values of your global variables stated above. If not using, copy the name in front of the "YourValueName"

sleepStateMapping = {Sleeping="Sleeping", Awake="Awake"};

timeOfDayMapping = {Morning="Morning", Day="Day", Evening="Evening", Night="Night"};

presentStateMapping = {Home="Home", Away="Away", Holiday="Holiday"};

-- Set the lux value for which the lights have to be turned on.

-- If you don't want to use the MinLux then just set it to: 65535

minLuxMorning = 20;

minLuxDay = 20;

minLuxEvening = 20;

minLuxNight = 20;

--[[

Now the most important part:

Here you can enter what light, for how long and at what value has to be turned on.

Leave empty brackets for no lights.

To set the light value without timer use 2 parameters: {LightID, "VALUE"}

To set the light value with timer use 3 parameters: {LightID, "VALUE", timeInSeconds }

To set the light value with the

automatic lights virtual device. use 4 parameters: {LightID, "VALUE", "timeInSeconds", VirtualDeviceSliderID} --]]

lightsSleeping = {}; --lights that are triggered when Sleepstate is sleeping.

lightsMorning = {{11, "30", 600}};

lightsDay = {{7, "99", 300},{11, "99", 300}};

lightsEvening = {{7, "99", 900},{11, "90", 900}};

lightsNight = {};

--Manual Override, the time that lights will not be turned ON again after manually turning them off.

OverrideFor = 30;

--------------------------------------------------------------------

-------------------------EXTRA FEATURES-----------------------------

extraMorningFunc = function()

-- Add your extra code here. If you want some checks or maybe run a virtual device button.

--This code is always triggered if there is motion.

-- movieLights = {{180, "10"},{181, "10"} };

--if (xbmc == "playing" ) then CallLightArray(movieLights);

ExtraDebug("Extra morning function called");

end

extraDayFunc = function()

-- Add your extra code here. If you want some checks or maybe run a virtual device button.

--This code is always triggered if there is motion.

ExtraDebug("Extra day function called");

end

extraEveningFunc = function()

-- Add your extra code here. If you want some checks or maybe run a virtual device button.

--This code is always triggered if there is motion.

ExtraDebug("Extra evening function called");

end

extraNightFunc = function()

-- Add your extra code here. If you want some checks or maybe run a virtual device button.

--This code is always triggered if there is motion.

ExtraDebug("Extra night function called");

end

extraLightTriggerChecks = function()

--add extra checks here. and return the total true or false value.

--if returning false the lights will not be triggered.

-- for instance: return ( (pcTurnedOff == true ) and (xbmc ~= "Empty") );

return ( true );

end

--------------------------------------------------------------------

----------------------ADVANCES SETTINGS-----------------------------

local showStandardDebugInfo = true; -- Debug shown in white

local showExtraDebugInfo = true; -- Debug shown in orange

--------------------------------------------------------------------

--------------------------------------------------------------------

-- DO NOT CHANGE THE CODE BELOW --

--------------------------------------------------------------------

--UPDATE FROM HERE

local startSource = fibaro:getSourceTrigger();

local motionSensorStatus = tonumber(fibaro:getValue(motionSensorID, "value"));

local motionSensorArmed = tonumber(fibaro:getValue(motionSensorID, "armed"));

local lux = tonumber(fibaro:getValue(LuxSensorID, "value"));

local keepLightsOn = false;

local timerRunning = false;

version = "1.4.4";

SavedState = {

homeStatus = "",

timeOfDay = "",

lux = 0,

motion = 0,

startTime = 0,

sleepState = 0

}

Debug = function ( color, message )

fibaro:debug(string.format('<%s style="color:%s;">%s%s>', "span", color, message, "span"));

end

--Making sure that only one instance of the scene is running.

fibaro:sleep(50); --sleep to prevent all instances being killed.

if (fibaro:countScenes() > 1) then

if (showExtraDebugInfo) then

Debug( "grey", "Abort, Scene count = " .. fibaro:countScenes());

end

fibaro:abort();

end

--------------------------EXECUTION----------------------------------

SetCurrentStatus = function ()

ExtraDebug("Saving current variable statusses");

SavedState.homeStatus = GetPresentState();

SavedState.timeOfDay = GetTimeOfDay();

SavedState.sleepState = GetSleepState();

SavedState.lux = tonumber(fibaro:getValue(LuxSensorID, "value"));

SavedState.motion = tonumber(fibaro:getValue(motionSensorID, "value"));

end

CheckStatusChanges = function ()

ExtraDebug("Status change check");

if (GetPresentState() ~= SavedState.homeStatus ) or (GetTimeOfDay() ~= SavedState.timeOfDay ) then

SceneTriggered();

end

SetCurrentStatus();

-- we still have a motion so reset timer.

if (SavedState.motion ~= 0 ) then

ExtraDebug( "Resetting time" );

SavedState.startTime = os.time();

end

--any other case, we are not resetting the timer.

end

ManualOverRideCheck = function ( lightArray )

ExtraDebug("Manual override check");

for i = 1, #lightArray do

if ( #lightArray == 3) then

tmpId = lightArray[1];

if (tonumber(fibaro:getValue(tmpId, "value")) == 0 and lightArray["OffMode"] ~= "ByScene" ) then

ExtraDebug( "Manual override for light: " .. tmpId .. "active" );

lightArray["OffMode"] = "ManualOverride";

end

end

end

end

LightsOff = function ( lightArray )

local stillLightsOn = 0;

for i = 1,#lightArray do

if ( #lightArray == 3) then

tmpId = lightArray[1];

--On till:

timeL = SavedState.startTime + (lightArray[3]);

currentTime = os.time();

timeLeft = timeL - currentTime;

ExtraDebug("TimeLeft: " .. timeLeft .. " seconds" );

if ( timeLeft <= 0 ) then

fibaro:call(tmpId, "turnOff");

if ( lightArray["OffMode"] ~= "ManualOverride" ) then

lightArray["OffMode"] = "ByScene";

end

ExtraDebug("Switch off light: " .. tmpId);

elseif (tonumber(fibaro:getValue(tmpId, "value")) == 0 ) then

if ( lightArray["OffMode"] == "ManualOverride" ) then

ExtraDebug("Manual override for light: " .. tmpId .. "active, not turning on");

else

ExtraDebug("Turn light: " .. tmpId .. " back on");

fibaro:call(tmpId, "setValue", lightArray[2] );

end

else

lightArray["OffMode"] = "NoOverride";

stillLightsOn = stillLightsOn + 1;

end

end

end

return stillLightsOn;

end

KeepLightsOn = function ()

ExtraDebug("starting with while loop, to keep lights on");

SavedState.startTime = os.time();

SetCurrentStatus();

while ( keepLightsOn ) do

currentLightArray = GetTimeOfDayLightArray();

ManualOverRideCheck( currentLightArray );

CheckStatusChanges();

local stillLightsOn = 0;

stillLightsOn = LightsOff( currentLightArray );

if (stillLightsOn == 0 ) then

keepLightsOn = false;

RunManualOverrideMode( currentLightArray );

end

fibaro:sleep(1000);

ExtraDebug("--------------- next timer run ---------------");

end

end

RunManualOverrideMode = function ( currentLightArray )

ExtraDebug("-----------------Override Mode-------------");

OverrideForAll = 0;

for i = 1,#currentLightArray do

if ( currentLightArray["OffMode"] == "ManualOverride" ) then

OverrideForAll = OverrideForAll +1;

end

end

if ( OverrideForAll ~= 0 and OverrideForAll == #currentLightArray ) then

OverrideTimer = os.time();

while ( (OverrideTimer + OverrideFor ) - os.time() > 0 ) do

ExtraDebug("Still in override for: " .. (OverrideTimer + OverrideFor ) - os.time() .. " seconds" );

fibaro:sleep(1000);

end

end

end

----------------------Turn lights on functions------------------------

CallLightArray = function( lightArray )

debugVariable = "Lights: " .. GetTimeOfDay();

if (#lightArray == 0 ) then

debugVariable = "No lights set for " .. GetTimeOfDay();

return;

end

-- StandardDebug(type(lightArray));

-- if type(lightArray) ~= "table" then

-- ErrorDebug("Missing brackets for: lights" .. GetTimeOfDay() .. ", place extra brackts: { } around.");

-- else

for i = 1,#lightArray do

tmpId = lightArray[1];

tmpValue = lightArray[2];

--TODO: check if values not nill

if ( #lightArray == 2 ) then

fibaro:call(tmpId, "setValue", tmpValue);

StandardDebug( "Set id: " .. tmpId .. " to Value: " .. tmpValue );

elseif ( #lightArray == 3 ) then

fibaro:call(tmpId, "setValue", tmpValue);

StandardDebug( "Set id: " .. tmpId .. " to Value: " .. tmpValue );

keepLightsOn = true;

elseif ( #lightArray == 4 ) then

tmpVdTime = lightArray[3];

tmpBtnId = lightArray[4];

--TODO: set light value first. then time slider.

--check if off... else just set time.

fibaro:call(tmpId, "setValue", tmpValue);

fibaro:sleep(300);

fibaro:call(AutoLightsVdId, "setSlider", tmpBtnId, tmpVdTime );

StandardDebug( "Set id: " .. tmpId .. " to Value: " .. tmpValue .. " for: " .. tmpVdTime .. " sec." );

end

-- end

end

if ( keepLightsOn and not timerRunning ) then

ExtraDebug("Starting timer, not yet running");

timerRunning = true;

KeepLightsOn();

else

ExtraDebug("Timer already running, returning");

end

end

LightperDayPart = function( minLux, lightArray )

if ( (GetPresentState() == presentStateMapping.Home ) and

(extraLightTriggerChecks() ) ) then

-- add check for current light state. (because of changed lux value)

-- if lights on and use of virtual device. then extend time. else nothing.

if ( lux > minLux ) then

StandardDebug( "Sensor lux: " .. lux .. " higher then minValue: " .. minLux .. " : no action");

else

StandardDebug("Sensor lux: " .. lux .. " is lower then minValue: " .. minLux);

CallLightArray( lightArray );

end

else

ExtraDebug("ExtraLightTriggerChecks or PresentState is false, so not lights");

end

end

SceneTriggered = function()

debugVariable = "No lights: " .. GetTimeOfDay();

if ( GetSleepState() == sleepStateMapping.Sleeping ) then

LightperDayPart( 65535, lightsSleeping );

elseif ( GetTimeOfDay() == timeOfDayMapping.Morning ) then

extraMorningFunc();

LightperDayPart( minLuxMorning, lightsMorning );

elseif ( GetTimeOfDay() == timeOfDayMapping.Day ) then

extraDayFunc();

LightperDayPart( minLuxDay, lightsDay );

elseif ( GetTimeOfDay() == timeOfDayMapping.Evening ) then

extraEveningFunc();

LightperDayPart( minLuxEvening, lightsEvening );

elseif ( GetTimeOfDay() == timeOfDayMapping.Night ) then

extraNightFunc();

LightperDayPart( minLuxNight, lightsNight );

end

StandardDebug(debugVariable);

end

------------------------STATUS functions------------------------------

GetTimeOfDay = function ()

return LookupGlobal( timeOfDay, "TimeOfDay", "Day");

end

GetSleepState = function ()

return LookupGlobal( sleepState, "sleepState", "Awake");

end

GetPresentState = function ()

return LookupGlobal( presentState, "presentState", "Home");

end

LookupGlobal = function ( name, stateName, default )

local ps = fibaro:getGlobalValue( name );

if ( (ps ~= "") and (ps ~= nil ) ) then

ExtraDebug("returned " .. stateName .. ": " .. ps );

return ps;

else

ErrorDebug( stateName .. " variable not found");

return default;

end

end

lightsStatus = function ( id )

--check if lights are already on.

allLights = {lightsSleeping, lightsMorning, lightsDay, lightsEvening, lightsNight };

for i = 1,#allLights do

for iL = 1, #allLights do

if ( allLights[iL][1] == tonumber(id) ) then

if ( fibaro:getValue(allLights[iL][1], "value") == "0" ) then

return "off";

else

return "on";

end

end

end

end

ErrorDebug("Light status unknown");

return "unknown";

end

GetTimeOfDayLightArray = function ()

if ( SavedState.sleepState == sleepStateMapping.Sleeping ) then

return lightsSleeping;

elseif ( SavedState.timeOfDay == timeOfDayMapping.Morning ) then

return lightsMorning;

elseif ( SavedState.timeOfDay == timeOfDayMapping.Day ) then

return lightsDay;

elseif ( SavedState.timeOfDay == timeOfDayMapping.Evening ) then

return lightsEvening;

elseif ( SavedState.timeOfDay == timeOfDayMapping.Night ) then

return lightsNight;

end

end

--------------------Debugging Functions-----------------------------

StandardDebug = function ( debugMessage )

if ( showStandardDebugInfo ) then

Debug( "white", debugMessage);

end

end

ExtraDebug = function ( debugMessage )

if ( showExtraDebugInfo ) then

Debug( "orange", debugMessage);

end

end

ErrorDebug = function ( debugMessage )

Debug( "red", "Error: " .. debugMessage);

end

TestDebug = function (debugMessage )

Debug( "blue", "Testing: " .. debugMessage );

end

----------------------START OF THE SCENE----------------------------

StandardDebug("Home status: " .. GetPresentState() );

StandardDebug("Motion status: " .. ( motionSensorStatus == 0 and "No movement" or "movement"));

if (startSource["type"] == "property") then

startSourceID = tonumber(startSource['deviceID']);

triggerDebug = "Triggered by: " .. startSourceID;

if ( startSourceID == motionSensorID ) then

StandardDebug( triggerDebug .. " Motion sensor" );

if ( motionSensorStatus > 0 ) then

SceneTriggered();

end

elseif ( startSourceID == LuxSensorID ) then

StandardDebug( triggerDebug .. " Lux sensor" );

ExtraDebug( "Lux value changed to: " .. lux );

if ( motionSensorStatus > 0 ) then

SceneTriggered();

end

elseif ( IsWalkDirection( startSourceID ) ) then

StandardDebug( triggerDebug .. " Walk Direction sensor" );

--walkDirection( startSourceID );

else

st = lightsStatus( startSourceID );

StandardDebug( triggerDebug .. " Light switch" );

if (st == "off") then

ExtraDebug( "light turned off, sleep 4 sec" );

--TODO: Call manual override.

fibaro:sleep(4000);

elseif (st == "on") then

ExtraDebug( "light turned on, sleep 4 sec" );

--TODO: call manual override, make time available to user.

fibaro:sleep(4000);

else

ErrorDebug( "Unknown light trigger" );

end

-- Maybe we can change the light preset to make it more intelligent.

-- maybe we can change the Lux preset to make it more intelligent.

end

elseif ( startSource["type"] == "global" ) then

StandardDebug( "Triggered by: " .. "global variable" );

if ( motionSensorStatus > 0 ) then

SceneTriggered();

end

else

StandardDebug( "Triggered by: " .. startSource["type"] );

--Just run the Light Code, not checking for motion. Probably triggered manually.

if ( startSource["type"] == "other" ) then

SceneTriggered();

end

end

Debug( "green", "Smart Lights V" .. version .. " | by Control Living, Finished" );

Debug( "green", "--------------------------------------------------" );

fibaro:abort(); --otherwise scene will stay alive to long.

--UPDATE TILL HERE

Thanks a lot in advance.

1 answer to this question

Recommended Posts

  • 0
Posted

Added it for you, there you go

Please login or register to see this image.

/emoticons/default_smile.png" alt=":)" srcset="https://forum.fibaro.com/uploads/emoticons/[email protected] 2x" width="20" height="20" />

Please login or register to see this link.

Let me know if it works as expected...

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Answer this question...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...