I just got my dataMine graphing plugin working, and I am trying to figure out the best way to graph the modestate of my thermostat (i.e. when it is heating, vice idle) which is a string (the graphing plugin apears to take numbers). Reading a lot of posts - I took a look at creating a binary switch, and setting up a 1 minute poll on the state, and flipping the switch. This seems overly complicated.
Option two, using the variable container plugin, and setting up a 1 minute poll to change that variable. Same thing - seems overly complicated.
Option three - any suggestions? Really, I just want to mirror the modestate variable as a 0/1 (or even 0/1/2 for off/heating/cooling). There must be a simple way to do this.
Hello - I wrote the below to accomplish the above, but it doesn’t seem to be working yet. I get no error when I save the code, but the variable (var1) never changes. I am really not sure if I am using the variable container plugin properly. I used the ‘advanced’ tab to add a variable, somehow ended up with two that have the same name. Screen capture below.
-- Create a local variable that contains the current state (Heating, Idle, Cooling) thermostat ID is 19 (this is not the altid)
-- and fetch the current value of var1 to put into the day_run that may be incremented if the HVAC is running
local day_run = luup.variable_get("urn:upnp-org:serviceId:VariableContainer","var1", 35)
local state = luup.variable_get("urn:upnp-org:device:HVAC_ZoneThermostat:1","ModeState", 19)
-- This needs to be reset every day at midnight
local t = os.date('*t')
local current_second = t.hour * 3600 + t.min * 60 + t.sec
if (current_second < 120) then
day_run = 0
end
-- Compare the state and increment if the HVAC is running.
if state == 'Heating' then
day_run = day_run + 1
elseif state == 'Cooling' then
day_run = day_run + 1
elseif state == 'Idle' then
day_idle = day_idle + 1
end
-- Variable container is device 35 - drop the variable into var1 of the variable container
luup.variable_set("urn:upnp-org:serviceId:VariableContainer","var1", day_run ,35)
There is a “ModeStatus” that’s part of urn:upnp-org:serviceId:HVAC_UserOperatingMode1, as well as the “ModeState” that’s part of “urn:micasaverde-com:serviceId:HVAC_OperatingState1”.
I don’t know why MCV defined a proprietary “micasaverde-com” service for operating state when there’s already a UPnP definition that covers it. If you look through the UI code and through the documentation, it seems MCV references ModeStatus in some places, and ModeState in others. (I wouldn’t be surprised if there are actually bugs related to this issue - maybe that’s what you’re running into)
They are two different things. One tells you whether the t-stat is set to Off, Heat, Cool, etc. mode; the other whether there currently is a call for heat / cool, etc.
Thanks for the input - I figured out how to watch the logs - and it seems that
local state = luup.variable_get(“urn:micasaverde-com:serviceID:HVAC_OperatingState1”,“ModeState”,19)
luup.log(“Debug fetch state=” … state)
throws the error
01 02/27/12 23:10:24.012 LuaInterface::CallFunction-3 Scene 28 failed [string “function scene_8()…”]:61: attempt to concatenate local ‘state’ (a nil value) <0x803>
Course, there is a little quantum mechanics here, is the error from trying to concatenate for the debug code, or the line before?
Ah, I am hot on the trail now, though it will have to wait until tomorrow. I will post the working code shortly!
They are two different things. One tells you whether the t-stat is set to Off, Heat, Cool, etc. mode; the other whether there currently is a call for heat / cool, etc.[/quote]
Actually, I believe ModeTarget (when read) is supposed to tell you if the t-stat mode is set to Off, Heat, or Cool, etc. and ModeStatus tell you whether there is currently a call for Heat, Cool, etc. That’s why ModeStatus has an “Idle/InDeadBand” value, but there is no equivalent “Idle” value for ModeTarget.
This mirrors the HVAC fan control service: FanTarget gets and sets the current fan operating mode (typically Auto or ContinuousOn), but FanStatus indicates whether or not the fan is currently running.
Whether or not MCV actually implemented it this way for their Z-Wave stats is not 100% clear, but that’s the way I implemented it in my HVAC plug-in as it appears to be the way the UPnP spec is written.
ModeTarget tells you the desired state (“I want the thermostat to go into this mode.”) while ModeStatus tells you the actual status (“The thermostat is in this mode.”). This is how MiOS interprets these values.
I am also interested in tracking and graphing ModeState on my thermostat. Let me know how this goes especially with how often you have to poll the device to get decent numbers. I have been holding off implementation because I don’t want to accidentally draw down the batteries while I am away doing lots of polling, but I figured every 5-10 minutes would be needed to make this work semi-accurately. Currently polling about once per hour.
Ok, so I apologize for beating a dead horse and also hijacking this thread to clarify the API spec, but I’d like to make sure I’ve got this right in my thermostat implementation. Are you saying that MiOS uses these variables in the following way:
Heating / Cooling:
[ul][li]ModeTarget - reflects requested mode (i.e. do we want the system to be heating or cooling or off)[/li]
[li]ModeStatus - also reflects current requested mode (possible with a slight lag while mode change is applied to thermostat). So if the system is idle (in dead zone), but is set to heat mode, this value will always be “HeatOn” not "InDeadZone?[/li]
[li]ModeState - reflects current operating status (ex. if the system is actively heating, this will be “Heating”, or “Idle” if the system is in the dead zone / idle)[/li][/ul]
Fan:
[ul][li]Mode - reflects requested fan mode (“ContinuousOn” - fan should run continuously, “Auto” - fan should cycle on and off as determined by the tstat)[/li]
[li]FanStatus - reflects current fan status (“On” - fan is running, “Off” - fan is not currently running)[/li][/ul]
So ModeState was added by MCV because apparently the UPnP spec does not provide a way to query the current operating status (actively heating, or cooling, or idle), right?
If this is the way MCV uses these values I’ll update my thermostat plug-in to match.
However, the extra state values for ModeStatus in the UPnP spec (as opposed to ModeTarget) combined with the fact that FanStatus was “live status” in the Fan service, did make me think that ModeStatus was supposed to be a live “status” for heating / cooling instead of just a reflection of the whatever was set for the current operating mode. For example, the following values are valid for ModeStatus but can never be set using ModeTarget:
InDeadZone (renamed from Idle in earlier spec version)
EnergySavingsHeating
EnergySavingsCooling
So how does ModeStatus ever end up in “InDeadZone” if “InDeadZone” can never me set via ModeTarget?
[ul][li]ModeTarget - the desired mode (e.g. “I want the thermostat to go into Cooling mode.”)[/li]
[li]ModeStatus - the actual mode (“The thermostat is currently in Heating mode.”)[/li]
[li]ModeState - what the thermostat is currently doing (“The thermostat is currently Idle.”)[/li][/ul]
Not all ModeStatuses are supported by the thermostats or by the Vera UI (the MiOS engine should support all the statuses). I think that InDeadBand is one such ModeStatus.
Thanks for taking the time to clarify. I’ll make sure to use the variables your way in my wifi tstat plugin. (Actually, I was doing it your way originally, but had changed it after rereading the UPnP spec and some pages in the wiki.)
Ok, I have had this running for about a week now and it seems to be doing ok. (I did have a crash of the vera last week, which has only happened one time in the last 9 months, so I was a bit concerned, but it seems ok now.) It does look like it didn’t ‘reset’ on the 16th. Not sure what happened there.
FYI, I picked a 1 minute poll because the lockout period for the heat cycling is about 90 seconds. I also have gas, which tends to cycle more than heat pump (except in the summer of course).
Also - my ultimate goal is to use the ‘notification’ that comes across the ‘wire’ when the State changes. When I figured out how to watch the live log, I realized that the thermostat pushes a notification that the log ‘sees’ when it changes. If I figure out how to capture that, I could get an exact on/off time without taking lots of polling/data. Of course, to do this I will have to quit my job and sit around and watch the log file all day. Oh, and get a divorce.
Note that in the picture below, you can see that the heat was running in the early part, then nothing ran for a couple days. Then I started to run the A/C in the last couple days.
[code]-- Create a local variable that contains the current state (Heating, Idle, Cooling) thermostat ID is 19 (this is not the altid)
– and fetch the current value of Variable1 to put into the day_run that may be incremented if the HVAC is running
local day_idle = luup.variable_get(“urn:upnp-org:serviceId:VContainer1”,“Variable2”,35)
local day_run = luup.variable_get(“urn:upnp-org:serviceId:VContainer1”,“Variable1”,35)
luup.log(“Debug fetch day_run=” … day_run)
local state = luup.variable_get(“urn:micasaverde-com:serviceId:HVAC_OperatingState1”,“ModeState”,19)
luup.log(“Debug fetch state=” … state)
– This needs to be reset every day at midnight
local t = os.date(‘*t’)
local current_second = t.hour * 3600 + t.min * 60 + t.sec
if (current_second < 120) then
day_run = 0
day_idle = 0
luup.log(“Debug zeroed day_run=” … day_run)
end
– Compare the state and increment if the HVAC is running.
if state == ‘Heating’ then
day_run = day_run + 1
luup.log(“Debug increment HEATING=” … day_run)
elseif state == ‘Cooling’ then
day_run = day_run + 1
elseif state == ‘Idle’ then
day_idle = day_idle + 1
luup.log(“Debug increment IDLE=” … day_idle)
end
– Variable container is device 35
luup.variable_set(“urn:upnp-org:serviceId:VContainer1”,“Variable1”,day_run,35)
luup.variable_set(“urn:upnp-org:serviceId:VContainer1”,“Variable2”,day_idle,35)[/code]
Best Home Automation shopping experience. Shop at Ezlo!