some key functions:
- everything can be adjust by uservariables
- script tells you when uservariables are missing
- complete logging with usefull options
- usefull notifacations (not only switched time but also reasons why the screen is up)
- nice printing to domoticz log
-safety options like: manual usage for a max period. so when you left and manual is on, system override after a x period.
- buienradar + Weatherunderground + optional own sensors
Download
https://drive.google.com/folderview?id= ... sp=sharing
here you can find: 1-Functions script, 2-Sunscreen script and Documentation of script and variables.
Wiki ...
I post it when some other users are also satisfied and can confirm there are no bugs and documentation is valid!
Please reply with bugs / improvements / ideas or questions..
Help Wanted!
Documentation is always a problem you if you want to help documenting you can edit the documentation:
https://docs.google.com/spreadsheets/d/ ... sp=sharing
Code: Select all
-- Time Sunscreen
-- Check the (weather)conditions for controlling the Suncreen.
--
-- Release notes:
-- *104 12-07-2015 Using user variables instead of the normal variables
-- *105 15-07-2015 Open/Closed commando variabel, Start bash shell after change
-- *106 23-07-2015 Buienradar, Layout logfile, logfile name with ~d / ~m
--------------------------------------------------------------------------------
-- Variable
--
Script = 'Time Sunscreen' --
Version = 106 --
VersionLog = 106 --
Version_Type = 'Beta 01' --
Man_or_Auto = 'Auto' -- Default
package.path = package.path .. ';' .. '/home/pi/domoticz/scripts/lua/?.lua'
My = require('MyFunc')
--------------------------------------------------------------------------------
-- Functions
--
function SendANotification()
commandArray['SendNotification']='Sunscreen ' .. NewState .. '#Sunscreen ' .. DeviceName .. ' was in state ' .. CurState .. ' new state is ' .. NewState .. ', reason for change is ' .. My.EnumClear(Reason) .. ' / '.. os.date("%Y-%m-%d;%H:%M:%S").. '#0#pushover'
end
function LogActions()
LogFile=string.gsub(LogFile,"~d",os.date("%Y-%m-%d"))
LogFile=string.gsub(LogFile,"~m",os.date("%Y-%m"))
if not My.File_exists(LogFile) then
f=io.open(LogFile,"a")
f:write("Datum ; Tijd ; DeviceName ; Man_or_Auto ; Current State ; New state ; Reason up ; Version #".. VersionLog .."# ; Version Type ; " ..
"Result_Daytime ; Result_Hour ; Result_Wind ; Result_Gust ; Result_Wu_Rain ; Result_Br_Rain ; Result_UvClose ; Result_Temperature_Close ; Result_UvOp ; Result_TemperatureOp ; Result ; "..
"Nu_Hour <".. TH_Hour .." ; Wu_Wind <=".. TH_Wind .. "; Wu_Gust <=".. TH_Gust .. "; Wu_Rain <=".. TH_Wu_Rain .. "; Br_Rain <=".. TH_Br_Rain .. " ; Wu_Uv <=".. TH_Uv_Close .. "/" .. TH_Uv_Open .. "; Wu_Temperature <=".. TH_Tp_Close .. "/".. TH_Tp_Open .. "; "..
"Uv Sim ; SwManStart ; SwManEnd ; Switch manual ; SwManDif ; Notifications ; LogAction ; SwitchTime ; SwitchDiff ; " ..
LogCap01 .. ";" .. LogCap02 .. ";" .. LogCap03)
f:write("\r\n")
else
f=io.open(LogFile,"r")
c=f:read("*line")
if string.match(c, "#" ..VersionLog .. "#") then
else
print(". Version of logfile ".. LogFile .." is not correct.")
end
f:close()
f=io.open(LogFile,"a")
end
f:write(os.date("%Y-%m-%d;%H:%M:%S") .. ";" .. DeviceName .. ";" .. Man_or_Auto .. ";" .. CurState .. ";" .. NewState .. ";" .. My.EnumClear(Reason) .. ";" .. Version .. ";" .. Version_Type .. ";" ..
Res_Dayl .. ";" .. Res_Hour .. ";" .. Res_Wind .. ";" .. Res_Gust .. ";" .. Res_WuRain .. ";" .. Res_BrRain .. ";" .. Res_UvCl .. ";" .. Res_TpCl .. ";" .. Res_UvOp .. ";" .. Res_TpOp .. ";".. Result .. ";" ..
Nu_Hour .. ";" .. Wu_Wind .. ";" .. Wu_Gust .. ";" .. Wu_Rain .. ";" .. Br_Rain .. ";".. Wu_Uv .. ";" .. Wu_Temp .. ";" ..
Uv_Sim .. ";" .. SwManStart .. ";" .. SwManEnd .. ";" .. Man_to_Auto .. ";" .. SwManDif .. ";" .. Notifications .. ";" .. LogAction .. ";" .. SwitchTime .. ";" .. SwitchDiff .. ";" ..
LogAdd01 .. ";" .. LogAdd02 .. ";" .. LogAdd03)
f:write("\r\n")
f:close()
end
--------------------------------------------------------------------------------
commandArray = {}
print ("______________________________________________________________________")
print (">> ".. Script .. ".......v" .. Version .. "....." .. Version_Type)
-- User variables
--
UserVarErr = 0
RunFast = My.GetUserVar("SUN_RunFast") -- 5
RunSlow = My.GetUserVar("SUN_RunSlow") -- 5
RunLast = My.GetUserVar("SUN_RunLast") -- 2015-07-29 18:30:00
if (timeofday['Daytime']) then RunEveryxMin=RunFast else RunEveryxMin=RunSlow end
TDiff = My.Round(My.TimeDiff(os.time(),RunLast)/60,0)
if TDiff < RunEveryxMin then
print (". Wait : ".. TDiff .. " / " .. RunEveryxMin)
goto done
end
nu=tostring(os.date ("%Y-%m-%d %H:%M:%S"))
commandArray['Variable:SUN_RunLast'] = nu
print (". ")
DeviceLuaMstr = My.GetUserVar("LUA_MasterSW") -- LUA_MasterSW
lat = My.GetUserVar("Gen_Latitude") + 0 --
lon = My.GetUserVar("Gen_Longitude") + 0 --
LogFile = My.GetUserVar("SUN_LogFile") -- /home/pi/log/Sunscreen.csv
DeviceName = My.GetUserVar("SUN_DeviceName") -- Sunscreen
DeviceManual = My.GetUserVar("SUN_DeviceManual") -- Sunscreen - Manual
DeviceAtHome = My.GetUserVar("SUN_DeviceAtHome") -- Not in use
DeviceTemp = My.GetUserVar("SUN_DeviceTemp") -- 45.00;NE;0;0;23.1;23.1 In most cases this is the wind device. Temperature is on position 5
DeviceRain = My.GetUserVar("SUN_DeviceRain") -- 0;0.0 Weather undergMy.Round Rain device
DeviceUvme = My.GetUserVar("SUN_DeviceUvme") -- 0.0;0.0 Weather undergMy.Round Uv device
DeviceBuien = My.GetUserVar("SUN_DeviceBuien") -- 2 Buienradar (under construction)
DeviceAddVal01 = My.GetUserVar("SUN_AddValue01") -- Temp_Livingroom
DeviceAddVal02 = My.GetUserVar("SUN_AddValue02") -- Temp_Bedroom
DeviceAddVal03 = My.GetUserVar("SUN_AddValue03") -- x
InstVersion = My.GetUserVar("SUN_InstVersion") -- 104
ActionClose = My.GetUserVar("SUN_ActionClose") -- On
ActionOpen = My.GetUserVar("SUN_ActionOpen") -- Off
ShAfterAction = My.GetUserVar("SUN_ShAfterAction") -- sudo /home/pi/domoticz/scripts/bash/log-dropbox.sh
TH_Wind = My.GetUserVar("SUN_TH_Wind") + 0 -- Treshold wind
TH_Gust = My.GetUserVar("SUN_TH_Gust") + 0 -- Treshold windstoten
TH_Wu_Rain = My.GetUserVar("SUN_TH_Wu_Rain") + 0 -- Treshold regen/neerslag
TH_Br_Rain = My.GetUserVar("SUN_TH_Br_Rain") + 0 -- Treshold regen/neerslag
TH_Uv_Close = My.GetUserVar("SUN_TH_Uv_Close") + 0 -- 2.5 -- treshold voor Uv close
TH_Uv_Open = My.GetUserVar("SUN_TH_Uv_Open") + 0 -- 1.5 -- treshold voor Uv open
TH_Tp_Close = My.GetUserVar("SUN_TH_Tp_Close") + 0 -- 20 -- treshold voor Temperature close
TH_Tp_Open = My.GetUserVar("SUN_TH_Tp_Open") + 0 -- 19 -- treshold voor Temperature close
TH_Hour = My.GetUserVar("SUN_TH_Hour") + 0 -- Treshold hour
ManualTime = My.GetUserVar("SUN_ManualTime") -- 'D' D=Daytime / A=All
Debugging = My.GetUserVar("SUN_Debugging") -- 'Y'
Man_to_Auto = My.GetUserVar("SUN_Man_to_Auto") + 0 -- 240 Minutes manual override
SwitchTime = My.GetUserVar("SUN_SwitchTime") + 0 -- 10
LogAction = My.GetUserVar("SUN_LogAction") -- 'Y' A=All, Y=Only on change
Notifications = My.GetUserVar("SUN_Notifications") -- 'Y' Y=Yes, N=No
if UserVarErr> 0 then
print (". Please check user variables.")
print (". ")
end
InstV=tonumber(InstVersion)
if InstV==nil then InstV=100 end
if InstV < Version then
print (". ")
print (". Registered version : " .. InstV .. " , running version : " .. Version )
print (". Not able to update automatically.")
print (". ")
-- commandArray['Variable:SUN_InstVersion']= tostring(Version)
goto done
end
if UserVarErr> 0 then goto done end
if (otherdevices[DeviceLuaMstr]) == 'Off' then
print (". LUA Master switch is off")
goto done
end
-- Variable
--
if (string.len(DeviceAddVal01)) > 1 then
LogCap01 = DeviceAddVal01 --
LogAdd01 = My.GetValue(otherdevices_svalues[DeviceAddVal01],1)
else
LogCap01 = "nvt" --
LogAdd01 = 0
end
if (string.len(DeviceAddVal02)) > 1 then
LogCap02 = DeviceAddVal02 --
LogAdd02 = My.GetValue(otherdevices_svalues[DeviceAddVal02],1)
else
LogCap02 = "nvt" --
LogAdd02 = 0
end
if (string.len(DeviceAddVal03)) > 1 then
LogCap03 = DeviceAddVal03 --
LogAdd03 = My.GetValue(otherdevices_svalues[DeviceAddVal03],1)
else
LogCap03 = "nvt" --
LogAdd03 = 0
end
--
-- Retrieve values from weather devices
--
Wu_Dev_Temp = otherdevices_svalues[DeviceTemp]
Wu_Dev_Rain = otherdevices_svalues[DeviceRain]
Wu_Dev_UvMe = otherdevices_svalues[DeviceUvme]
Br_Dev_Rain = otherdevices_svalues[DeviceBuien]
--
-- Split values from devices
--
Wu_Wind = My.GetValue(Wu_Dev_Temp,3)
Wu_Gust = My.GetValue(Wu_Dev_Temp,4)
Wu_Temp = My.GetValue(Wu_Dev_Temp,5)
Wu_Rain = My.GetValue(Wu_Dev_Rain,2)
Wu_Uv = My.GetValue(Wu_Dev_UvMe,1)
Nu_Hour=tonumber(os.date('%H',time))
Reason=""
Reascl=""
Reasop=""
Uv_Wim=""
--
-- Special correction for hot days
--
Uv_Sim=""
if Wu_Uv < TH_Uv_Close and Wu_Temp >= 20 and Nu_Hour >= 7 and Nu_Hour <= 9 then
Wu_Uv = TH_Uv_Close
Uv_Sim = "01 Hot day rule"
end
if Wu_Uv < TH_Uv_Close and Wu_Uv >= 0.1 and Wu_Temp >= 20 and Nu_Hour >= 9 and Nu_Hour <= 11 then
Wu_Uv = TH_Uv_Close
Uv_Sim = "02 Hot day rule"
end
--
-- Calculate pre results
-- Redenen om niet naar beneden te gaan
RainPrediction = My.Round(My.IsItGonnaRain(15, lat, lon),1)
-- Br_Rain=My.Round(10^((RainPrediction-109)/32),1)
Br_Rain = RainPrediction
if (timeofday['Daytime']) then Res_Dayl=1 else Res_Dayl=0 Reason=Reason .. "Sunrise ," end
if Nu_Hour < TH_Hour then Res_Hour=1 else Res_Hour=0 Reason=Reason .. "Hour " .. Nu_Hour .. " ," end
if Wu_Wind <= TH_Wind then Res_Wind=1 else Res_Wind=0 Reason=Reason .. "Wu Wind " .. Wu_Wind .. " ," end
if Wu_Gust <= TH_Gust then Res_Gust=1 else Res_Gust=0 Reason=Reason .. "Wu Gust " .. Wu_Gust .. " ," end
if Wu_Rain <= TH_Wu_Rain then Res_WuRain=1 else Res_WuRain=0 Reason=Reason .. "Wu Rain " .. Wu_Rain .. " ," end
if Br_Rain <= TH_Br_Rain then Res_BrRain=1 else Res_BrRain=0 Reason=Reason .. "Br Rain " .. Br_Rain .. " ," end
-- Redenen om niet naar beneden te gaan
if Wu_Uv >= TH_Uv_Close then Res_UvCl=1 else Res_UvCl=0 Reascl=Reascl .. "Wu Uv Closed " .. Wu_Uv .. " ," end
if Wu_Temp >= TH_Tp_Close then Res_TpCl=1 else Res_TpCl=0 Reascl=Reascl .. "Wu Temp Closed " .. Wu_Temp .. " ," end
-- Redenen om niet naar beneden te blijven (dus scherm omhoog)
if Wu_Uv >= TH_Uv_Open then Res_UvOp=1 else Res_UvOp=0 Reasop=Reasop .. "Wu Uv Open " .. Wu_Uv .. " ," end
if Wu_Temp >= TH_Tp_Open then Res_TpOp=1 else Res_TpOp=0 Reasop=Reasop .. "Wu Temp Open " .. Wu_Temp .. " ," end
--
-- Print decision info in the log
--
if (otherdevices[DeviceName]) == 'Open' then
print ( ". These conditions are valid when sunscreen is Up / Open: " )
else
print ( ". These conditions are valid when sunscreen is Down / Closed: " )
end
if (timeofday['Daytime']) then
print ( ". " .. Res_Dayl .. " - Daytime : True" )
else
print ( ". " .. Res_Dayl .. " - Daytime : False" )
end
print ( ". " .. Res_Hour .. " - Wu Hour : " .. Nu_Hour .. " <= Th : " .. TH_Hour )
print ( ". " .. Res_Wind .. " - Wu Wind : " .. Wu_Wind .. " <= Th : " .. TH_Wind )
print ( ". " .. Res_Gust .. " - Wu Gust : " .. Wu_Gust .. " <= Th : " .. TH_Gust )
print ( ". " .. Res_WuRain .. " - Wu Rain : " .. Wu_Rain .. " <= Th : " .. TH_Wu_Rain )
print ( ". " .. Res_BrRain .. " - Br Rain : " .. Br_Rain .. " <= Th : " .. TH_Br_Rain )
if (otherdevices[DeviceName]) == 'Open' then
print ( ". " .. Res_UvCl .. " - Wu Uv-i : " .. Wu_Uv .. " >= Th : " .. TH_Uv_Close .. " (Up / Open)")
print ( ". " .. Res_TpCl .. " - Wu Temp : " .. Wu_Temp .. " >= Th : " .. TH_Tp_Close .. " (Up / Open)")
Reason=Reason .. Reascl
Result = Res_Dayl + Res_Hour + Res_Wind + Res_Gust + Res_WuRain + Res_UvCl + Res_TpCl + Res_BrRain
else
print ( ". " .. Res_UvOp .. " - Wu Uv-i : " .. Wu_Uv .. " >= Th : " .. TH_Uv_Open .. " (Down / Closed)")
print ( ". " .. Res_TpOp .. " - Wu Temp : " .. Wu_Temp .. " >= Th : " .. TH_Tp_Open .. " (Down / Closed)")
Reason=Reason .. Reasop
Result = Res_Dayl + Res_Hour + Res_Wind + Res_Gust + Res_WuRain + Res_UvOp + Res_TpOp + Res_BrRain
end
print ( ". " .. Result .. " / 8 score.")
if (Wu_Rain<1 and Br_Rain>1) or (Br_Rain<1 and Wu_Rain>1) then
print ( ". Difference between WU and Buienradar result. WU : " .. Res_WuRain .. " Buienradar : " .. Res_BrRain)
end
--
-- Manual override for x minutes
--
SwManStart = otherdevices[DeviceManual]
TDiff = My.Round(My.TimeDiff(os.time(),otherdevices_lastupdate[DeviceManual])/60,0)
if (otherdevices[DeviceManual]) == 'On' then
print (". Last change manual state : " .. TDiff .. " minutes ago.")
if TDiff >= Man_to_Auto then
-- To long in manual mode, switch to auto
print(". Turn Manual switch off")
commandArray[DeviceManual] = 'Off'
end
if ManualTime~="D" and Res_Dayl==0 then
-- Outside daytime period, turn manual override off
print(". Turn Manual switch off, outside daytime")
commandArray[DeviceManual] = 'Off'
end
end
SwitchDiff = My.Round(My.TimeDiff(os.time(),otherdevices_lastupdate[DeviceName])/60,0)
-- print (". Last change screen state : " .. SwitchDiff .. " minutes ago.")
SwManEnd = otherdevices[DeviceManual]
SwManDif = TDiff
--
-- Current state Up / Open Change to Down / Closed ?
--
if (otherdevices[DeviceName]) == 'Open' then
CurState="Up / Open"
if Res_Dayl + Res_Hour + Res_Wind + Res_Gust + Res_WuRain + Res_UvCl + Res_TpCl + Res_BrRain == 8 then
if (otherdevices[DeviceManual]) == 'On' then
print (". Sunscreen Manual")
Man_or_Auto = 'Manual'
Reason=Reason .. " (Manual) , "
else
if SwitchDiff <= SwitchTime then
print (". Recent open, wait for switchtime")
Reason=Reason .. "Recent open , "
else
-- Closed
NewState = "Down / Closed"
print (". Action: Change to state : " .. NewState)
commandArray[DeviceName] = ActionClose
if Reason == "" then Reason = "No reason ," end
if Notifications == 'Y' then SendANotification() end
if LogAction == 'Y' or LogAction == 'A' then LogActions() end
if (string.len(ShAfterAction)) > 1 then os.execute(ShAfterAction) end
end
end
else
if (otherdevices[DeviceManual]) == 'On' then
print (". Sunscreen Manual")
Man_or_Auto = 'Manual'
Reason=Reason .. " (Manual) , "
end
print (". Action: None, Reason to stay in state Up / Open :")
end
end
--
-- Current state Down / Closed Change to Up / Open ?
--
if (otherdevices[DeviceName]) == 'Closed' or (otherdevices[DeviceName]) == 'Stopped' then
if (otherdevices[DeviceName]) == 'Closed' then CurState = "Down / Closed" else CurState="Stopped" end
if Res_Dayl + Res_Hour + Res_Wind + Res_Gust + Res_WuRain + Res_UvOp + Res_TpOp + Res_BrRain < 8 then
if (otherdevices[DeviceManual]) == 'On' then
print (". Sunscreen Manual")
Man_or_Auto = 'Manual'
Reason=Reason .. "Manual , "
else
-- Open
NewState = "Up / Open"
print (". Action: Change to state : " .. NewState)
commandArray[DeviceName] = ActionOpen
if Reason == "" then Reason = "No reason ," end
if Notifications == 'Y' then SendANotification() end
if LogAction == 'Y' or LogAction == 'A' then LogActions() end
if (string.len(ShAfterAction)) > 1 then os.execute(ShAfterAction) end
end
else
print (". Action: None (Down / Closed)")
end
end
NewState = "Idle"
if Reason == "" then Reason = "No reason ," end
print ( ". Reason: " .. My.EnumClear(Reason))
if LogAction=='A' then LogActions() end
::done::
print ("______________________________________________________________________")
return commandArray