Skip to content

Instantly share code, notes, and snippets.

@voodoojello
Last active June 15, 2016 13:58
Show Gist options
  • Save voodoojello/690a398df9b3e9ac1711 to your computer and use it in GitHub Desktop.
Save voodoojello/690a398df9b3e9ac1711 to your computer and use it in GitHub Desktop.
LUUP: AutoTherm - Set Thermostats by Inside/Outside Temp, Humidity, and Time of Day
module("auto_therm", package.seeall)
--
-- LUUP: AutoTherm - auto_therm.lua
-- Set Thermostats by Inside/Outside Temp, Humidity, and Time of Day
--
-- Authored: Mark Page [m.e.page_at_gmail.com]
-- Modified: Sat Mar 21 21:22:37 CDT 2015
--
-- Tested on Vera Lite - UI7 Version 7.0.2 (1.7.439)
-- Tested on Vera Edge - UI7 Version 7.0.5 (1.7.1018)
-- Tested using the Wunderground Weather Plugin - http://code.mios.com/trac/mios_weather
-- Tested using 2GIG CT100 Thermostats - https://www.2gig.com/products/ct100
--
-- For more info see: http://goo.gl/9b0QPP
--
function settherms()
----------------------------------------------------
-- User settings start here ------------------------
----------------------------------------------------
-- Vacation Mode - Set true to turn-off thermostats
local VacationMode = false
-- Desired Temp Settings
local DayHeatSetTemp = 73
local DayCoolSetTemp = 74
local NightHeatSetTemp = 68
local NightCoolSetTemp = 74
-- Heat or Cool threshold temp
local OSThresTemp = 66
-- Hour of day change over
local StartNightHour = 21
local EndNightHour = 3
-- Therm and sensor Device IDs
local OSTempDID = XX
local OSHumidDID = XX
local ThermDIDs = {XX,XX}
-- Multiplier to skew logarithmic equations for comfort.
-- Higher numbers result in colder/warmer settings.
-- Use caution as values >.05 may swing adjustments wildly!
local TempTweakIndx = .008
-- Used for sms/email notification through 3rd party RESTful API
local MsgAppURL = 'http://path.to/some/app'
local MsgAppPairs = '[name1=val1&name2=val2&]msg_txt_will_be_here='
----------------------------------------------------
-- User settings end here --------------------------
----------------------------------------------------
local OSCurrTemp = 50 -- fail-safe for calc on unexpected URN nil return
local OSCurrHumid = 50 -- fail-safe for calc on unexpected URN nil return
local DebugMode = false -- Off-device debugging. Will not run on Vera if set to true!
local HourOfDay = os.date('*t').hour
local datetime = os.date()
local http = require("socket.http")
local ISTemp = ""
local DevName = ""
local _return = ""
if (DebugMode) then
OSCurrTemp = arg[1]
OSCurrHumid = arg[2]
else
OSCurrTemp = luup.variable_get("urn:upnp-org:serviceId:TemperatureSensor1", "CurrentTemperature", OSTempDID)
OSCurrHumid = luup.variable_get("urn:micasaverde-com:serviceId:HumiditySensor1", "CurrentLevel", OSHumidDID)
end
OSCurrTemp = tonumber(OSCurrTemp)
OSCurrHumid = tonumber(OSCurrHumid)
for _, _did in pairs (ThermDIDs) do
local SetMode = "Cool"
local SetTemp = DayCoolSetTemp
local DayNight = "Day"
if (HourOfDay >= StartNightHour or HourOfDay <= EndNightHour) then
SetTemp = NightCoolSetTemp
DayNight = "Night"
end
if (OSCurrTemp < OSThresTemp) then
SetMode = "Heat"
SetTemp = DayHeatSetTemp
if (HourOfDay >= StartNightHour or HourOfDay <= EndNightHour) then
SetTemp = NightHeatSetTemp
DayNight = "Night"
end
end
local DevMode = SetMode .. "On"
local ModeSID = "urn:upnp-org:serviceId:HVAC_UserOperatingMode1"
local TempSID = "urn:upnp-org:serviceId:TemperatureSetpoint1_" .. SetMode
-- Inside temperature as reported by thermostat
if (DebugMode) then
ISTemp = arg[3]
else
ISTemp = luup.variable_get("urn:upnp-org:serviceId:TemperatureSensor1", "CurrentTemperature", _did)
end
-- Device name attribute from DID
if (DebugMode) then
DevName = "Dummy" .. _did
else
DevName = luup.attr_get('name', _did)
end
-- Primitive temperature index calculations with logarithmic adjustment.
-- Reference: http://www.wpc.ncep.noaa.gov/html/heatindex_equation.shtml
local HeatIndx = math.log(0.5 * (SetTemp + 61.0 + ((SetTemp-68.0)*1.2) + (OSCurrHumid*0.094)))
local TempIndx = math.log(OSCurrTemp)
-- Tweak set temp based on indexes and current inside temp
local DevTemp = ((SetTemp - TempIndx) + HeatIndx) - (ISTemp*TempTweakIndx)
DevTemp = string.format("%.1f", DevTemp - ((TempIndx + HeatIndx)/SetTemp))
-- Turn off thermostats if "VacationMode" set to "True"
if (VacationMode) then
DevMode = 'Off'
SetMode = 'Off - Vacation Mode'
end
-- For whatever reason luup.call_action will occasionally miss.
-- We'll call it twice just to be sure luup gets the events.
if not (DebugMode) then
for l = 0, 1, 1 do
luup.call_action(ModeSID, "SetModeTarget", {NewModeTarget = DevMode}, _did)
luup.sleep(500)
luup.call_action(TempSID, "SetCurrentSetpoint", {NewCurrentSetpoint = DevTemp}, _did)
luup.sleep(500)
end
end
local heat_ndex = string.format("%.2f", HeatIndx)
local temp_ndex = string.format("%.2f", TempIndx)
_return = _return .. string.format("Thermostat %s [ID%s] set to %s\194\176 (%s/%s) -- [S:%s\194\176, I:%s\194\176, O:%s\194\176, H:%s%%, HI:%s\194\176, TI:%s\194\176]\n\n", DevName, _did, DevTemp, SetMode, DayNight, SetTemp, DevTemp, OSCurrTemp, OSCurrHumid, heat_ndex, temp_ndex)
end
if (DebugMode) then
print (_return)
else
if (MsgAppURL) then
local _request = MsgAppPairs .. datetime .. "\n\n" .. _return
local _sendmsg = http.request(MsgAppURL, _request)
end
end
return _return
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment