Hello, got my Veralite one week ago, and I already got a pretty satisfying presence sim running, without too much hassle. I’m putting this here in case anyone is interested in this, and also, for anyone to review and tell me what I could have done better (especially in Lua, since I didn’t know this language 2 weeks ago)
For this, I use : 2 on/off modules, 1 light bulb socket module, a 4in1 sensor, and a 4keys mini remote, as well as a virtual switch plugin and a Chumby Radio.
The idea is the following :
- The sim is running once every hour, all the time
- When I leave the house, I use the 1st button of my remove to set the virtual switch to on (as well as giving me a feedback, by turning on then off one light).
- When I come back, I use the second button of the remote to set the virtual switch off (and put the lights back on, so I can use them normally)
- The sim checks this virtual switch and does nothing if it is not on
- If it is on, it calculates a random uptime for the radio, and sends the corresponding requests (see below), but only on even hours
- It also, depending on the luminosity, will calculate a random uptime for each light.
- I log everything the sim is doing on the radio (again, see below).
Regarding the radio, the great thing about the Chumby is that it’s running on a mini-Unix, with a light http server. So, I developped some basic cgi scripts to accept http requests, and transform them into Chumby events. If anyone needs to know how to do that, let me know, I’d be glad to share.
The Veralite sim code :
local mRandom = math.random
local sFormat = string.format
-- Turn a light on or off
function TurnLight(ValueAndId)
local value = string.sub(ValueAndId, 1, 1)
local id = string.sub(ValueAndId, 3, string.len(ValueAndId))
if (value == "0") then
LogToRadio(sFormat("Sim:TurnLightOff:%s",id))
else
LogToRadio(sFormat("Sim:TurnLightOn:%s",id))
end
luup.call_action("urn:upnp-org:serviceId:SwitchPower1", "SetTarget", {newTargetValue = value}, tonumber(id))
end
-- Send an http request to Chumby
function CommandRadio(Cmd)
local url=sFormat("%s,%s","http://192.168.1.102/cgi-bin/custom/control.cgi?Radio",Cmd)
local status, result = luup.inet.wget(url, 10)
end
-- Log something to Chumby through http
function LogToRadio(Info)
local url=sFormat("%s,%s","http://192.168.1.102/cgi-bin/custom/control.cgi?Log",Info)
local status, result = luup.inet.wget(url, 10)
end
function StartRadio()
LogToRadio("Sim:StartingRadio")
-- Get out of night mode
CommandRadio("DayMode")
-- Start music
CommandRadio("StartMusic")
-- Set Volume to max
CommandRadio("SetMaxVolume")
end
function StopRadio()
LogToRadio("Sim:StoppingRadio")
-- Set Volume to middle
CommandRadio("SetMidVolume")
-- Stop music
CommandRadio("StopMusic")
-- Night Mode
CommandRadio("NightMode")
end
-- verify if Vswitch away is on, otherwise, we end here
local Away = luup.variable_get("urn:upnp-org:serviceId:VSwitch1", "Status", 6)
if (Away == "0") then
luup.variable_set("urn:upnp-org:serviceId:VSwitch1", "Text1", "NoSim", 9)
luup.variable_set("urn:upnp-org:serviceId:VSwitch1", "Text2", "Home", 9)
return false
else
luup.variable_set("urn:upnp-org:serviceId:VSwitch1", "Text1", "SimOk", 9)
luup.variable_set("urn:upnp-org:serviceId:VSwitch1", "Text2", "Away", 9)
end
local tDevices = {
{Name="Radio", id=0, DelayMin=1, DelayMax=10, TimeOnMin=5, TimeOnMax=45, Threshold=0 },
{Name="Kitchen", id=4, DelayMin=1, DelayMax=45, TimeOnMin=1, TimeOnMax=10, Threshold=30 },
{Name="LivRoom", id=3, DelayMin=1, DelayMax=45, TimeOnMin=1, TimeOnMax=10, Threshold=60 },
{Name="Desktop", id=15, DelayMin=1, DelayMax=45, TimeOnMin=1, TimeOnMax=10, Threshold=100}
}
-- Force a poll of the 4in1 sensor before going on with the rest of the code
-- works, but does not wait for the end of the poll, so, useless
-- local nill, nill, jobid, nill = luup.call_action("urn:micasaverde-com:serviceId:HaDevice1", "Poll", {}, 11)
local CurrentLight = luup.variable_get("urn:micasaverde-com:serviceId:LightSensor1", "CurrentLevel", 11)
local CurrentTemp = luup.variable_get("urn:upnp-org:serviceId:TemperatureSensor1", "CurrentTemperature", 11)
LogToRadio(sFormat("LightLevel:%s",CurrentLight))
LogToRadio(sFormat("TempLevel:%s",CurrentTemp))
-- get current hour, radio will be on only if hour is even
local Radio=math.fmod(tonumber(os.date("%k")),2)
if (Radio == 0) then
local Delay = mRandom(tDevices[1].DelayMin, tDevices[1].DelayMax)
local TimeOn= mRandom(tDevices[1].TimeOnMin, tDevices[1].TimeOnMax)
local trace=sFormat("Sim:Radio:in_%d_min:for_%d_min",Delay,TimeOn)
Delay=Delay*60
TimeOn=TimeOn*60
luup.call_timer("StartRadio", 1, Delay, "", "")
luup.call_timer("StopRadio", 1, Delay + TimeOn, "", "")
LogToRadio(trace)
else
LogToRadio("Sim:Radio:off")
end
-- Loop for the lights
for i = 2,4 do
local trace=""
if (tonumber(CurrentLight) < tDevices[i].Threshold) then
local Delay = mRandom(tDevices[i].DelayMin, tDevices[i].DelayMax)
local TimeOn= mRandom(tDevices[i].TimeOnMin, tDevices[i].TimeOnMax)
trace=sFormat("Sim:Light%s(%d):in_%d_min:for_%d_min",tDevices[i].Name,tDevices[i].Threshold,Delay,TimeOn)
Delay=Delay*60
TimeOn=TimeOn*60
luup.call_timer("TurnLight", 1 ,Delay, "", sFormat("1,%d",tDevices[i].id))
luup.call_timer("TurnLight", 1 ,Delay + TimeOn, "", sFormat("0,%d",tDevices[i].id))
else
trace=sFormat("Sim:Light%s(%d):TooMuchLight",tDevices[i].Name,tDevices[i].Threshold)
end
LogToRadio(trace)
end
Now, I just need to find good values for the random delays and up times, as well as light levels. But other than that, it seems to work pretty well, here are some logs from a few tests today :
20130216-1715 : LightLevel:869
20130216-1715 : TempLevel:23
20130216-1715 : Sim:Radio:off
20130216-1715 : Sim:LightKitchen(50):TooMuchLight
20130216-1715 : Sim:LightLivRoom(50):TooMuchLight
20130216-1715 : Sim:LightDesktop(100):TooMuchLight
20130216-1911 : LightLevel:5
20130216-1911 : TempLevel:24
20130216-1911 : Sim:Radio:off
20130216-1911 : Sim:LightKitchen(30):in_36_min:for_2_min
20130216-1911 : Sim:LightLivRoom(60):in_38_min:for_3_min
20130216-1911 : Sim:LightDesktop(100):in_27_min:for_8_min
20130216-1938 : Sim:TurnLightOn:15
20130216-1946 : Sim:TurnLightOff:15
20130216-1947 : Sim:TurnLightOn:4
20130216-1949 : Sim:TurnLightOff:4
20130216-1949 : Sim:TurnLightOn:3
20130216-1952 : Sim:TurnLightOff:3
20130216-2011 : LightLevel:1
20130216-2011 : TempLevel:24
20130216-2011 : Sim:Radio:in_6_min:for_25_min
20130216-2011 : Sim:LightKitchen(30):in_22_min:for_9_min
20130216-2011 : Sim:LightLivRoom(60):in_22_min:for_9_min
20130216-2011 : Sim:LightDesktop(100):in_36_min:for_9_min
20130216-2017 : Sim:StartingRadio
20130216-2033 : Sim:TurnLightOn:4
20130216-2033 : Sim:TurnLightOn:3
20130216-2042 : Sim:StoppingRadio
20130216-2042 : Sim:TurnLightOff:4
20130216-2042 : Sim:TurnLightOff:3
20130216-2047 : Sim:TurnLightOn:15
20130216-2056 : Sim:TurnLightOff:15
The random numbers do not always look very random to me, but whatever, pretty happy with my purchase, and thanks to those who helped with my initial questions
Regards.