Charmed Quark Systems, Ltd. - Support Forums and Community
RunTimer2 driver - Printable Version

+- Charmed Quark Systems, Ltd. - Support Forums and Community (
+-- Forum: General Discussion (
+--- Forum: Driver Development (
+--- Thread: RunTimer2 driver (/showthread.php?tid=7870)

Pages: 1 2

RunTimer2 driver - rbroders - 09-12-2012

I wanted something that could track historical device usage in my home, so I created the RunTimer2 driver.  It doesn't create a lot of fields (five per timer), but it does have a powerful reporting mechanism based on TextLists and the StaticListBrowser.  I have included the driver, some pictures and a popup template for viewing the data. ┬Here is the driver documentation

Broderware/Run Timer2

This driver gives the ability to record and track statistics about how often and how long a device has been running.
 It provides field information about the duration of the current run, the number and duration of runs in the last 24 hours.
 It also provides a StringList based report mechanism which lists all runs in the last 24 hours, and d/w/m/y summary information.
 The driver also allows you to configure the time at which your day begins (default 00:00:00) for summary and Today information.

Quirks and Limitations:
The 24 hour state of all timers is saved in a file when the driver shuts down (and every 20minutes). 
When the driver restarts it will read this state and seamlessly continue its work if the state is less than a day old.
Any device transitions that occur during the downtime will, of course, be missed. 
However the driver will react to new state when it restarts, so if a device was off when this driver shutdown and it
is on when the driver restarts, this driver will assume the device has just turned on.
The daily summary information for each timer is stored in a spreadsheet friendly csv file
CQC\CQCData\MacroFileRoot\Drivers\RunTimer2\<moniker>_<timer>_daily.csv at the beginning of each new day.
If this driver is not running at the beginning of the day summary information will be lost for the previous day.

To find out if the timed device is on or off with high accuracy, the driver relies on field triggers and a single event (described below).
Polling is available as an option as well and is performed at 10 second intervals.

Connection Details:
This driver does not make a connection to any device or port.  It uses SimpleFldClient to talk to other drivers.

Config File
Timers must be configured by creating a file
Each line contains TimerName, Moniker.FieldName[!], RunningValue, Comparator, startDelay, stopDelay (params after RunningValue optional)
The ! after FieldName indicates that polling is required for this timer.
The Comparator parameter indicates the desired comparison.  So far = (default), >, and < are supplied.
Comparisons are now performed in the field's data type.  Note: Time data is a TimeStamp in Hex (i.e. 0x36B9DDA7D46140)
StartDelay and StopDelay (seconds) are used for devices that glitch a little, but aren't truly started (or stopped)
until they have been in the new state for a while.
Here are some sample lines from my config file:
AtticFan, Security.Output020, True
SpaHeat, Pool.SpaHeatActive, True
FurnaceALow, FurnaceA.S1_Demand, 1
FurnaceAMed, FurnaceA.S1_Demand, 2
FurnaceAHigh, FurnaceA.S1_Demand, 3
FrontDoor, Security.PhysZone001, Violated
LaundryWasher, Power2.RESMON#LaundryWasher~Watts, 6, >, 5, 10
LaundryDryer, Power2-.RESMON#LaundryDryer~Watts!, 20, >
TimeTest, Variables.CarTimeWest, 0x36B9DDA7D46140, >
PGEPowerFail, Power1.RESMON#Panel~Voltage, 100, <

Field names are created automatically for a given run timer name.
Because of that, the names entered during the driver install process must be unique, and conform to normal field naming restrictions.
To force the driver to reload its configuration, use the Server Administration window to Pause/Resume the driver.

Driver Fields
<Name>_TimeThisRun  R  Time  Duration of the current run if running, zero otherwise
<Name>_Runs24HRs    R  Card4 Number of runs in the last 24 hours
<Name>_Time24HRs    R  Time  Total Run Time in the last 24 hours
<Name>_RunsToday    R  Card4 Number of runs today (since the beginning of the day)
<Name>_TimeToday    R  Time  Total Run Time today (since the beginning of the day)
To notify the driver that a timer has turned on or off you can send it a command:

To support non-polled fields add a Trigger to the timer fields, and create a single event to call the driver.
To reduce the number of events for fields that have lots of values (i.e. Watts) only send triggers if expression is true,
use the identical expression, and enable Bidirectional latching (Dean added this for me in 5.3.913).
Here is the event you need:
Is Field Change
Is Device Ready     this_moniker
Logic: All True
Devices::SendDrvCmd(this_moniker, %(TEvRTV:SrcField), %(TEvRTV:NewFldVal))

This driver supports the QueryText function for extracting detailed report information.
The ID should be set to the TimerName, and the Value should be one of:
24HRs          Returns a stringlist with start, stop and elapsed time for all runs in the last 24HRs
24HRs.Runs  Returns the number of runs started in the last 24HRs (get the stringlist first)
24HRs.Time  Returns the total run time in the last 24HRs HH:MM:SS (get the stringlist first)
Today          Returns a stringlist with start, stop and elapsed time for all runs today
Today.Runs  Returns the number of runs today (get the stringlist first)
Today.Time  Returns the total run time today HH:MM:SS (get the stringlist first)
Daily           Returns a stringlist with the date, number of runs, total time for all days (including today)
Weekly        Returns the list of data summarized by week
Monthly       Returns the list of data summarized by month
Yearly         Returns the list of data summarized by year
<type>!      The ! modifier eliminates uninteresting periods (i.e. no runs and no time)
<type>.Periods Returns the total number of periods in the result (get the stringlist first)
<type>.Runs  Returns the total number of runs ever (get the stringlist first)
<type>.Time  Returns the total run time ever DD:HH:MM (get the stringlist first)
<type>.Lines Returns the total number of lines in the daily log file (get the stringlist first)
<type>.LastPeriodRuns  Returns the number of runs in the last (current) period (get the stringlist first)
<type>.LastPeriodTime  Returns the runtime of the last (current) period (get the stringlist first)
Also note: after the period name you might see an *, this means there was some missing data during that period.
If you see an !, it means there is no data at all for the period.

Hopefully graphing support will be added in the future...

RunTimers2 driver - ControlFreak - 09-17-2012

this looks great. Thanks for sharing.

An idea for an extension would be to allow calculation of energy cost per load.

You could expand input file to have a value of "max watts". (e.g., 300 for a switch leg with three 100-watt bulbs).

And the logic would have to change: instead of just tracking "on" or "2" you would track percent on (to handle dimmable fixtures).

Then poll every 2 minutes, when the dimmer value is non-zero, take the watts times the dim value times 2 minutes (1/30 hr) and add that to a running kWhr timer for that fixture.

I'm only interested in kWhrs, not dollar calcs, but others are probably interested in dollar calcs especially when time of use rates apply to them so an advanced version would have accept rate info.

OK, this was not really an "extension"...more of a fork...But a related idea. It would be great to help get fine grain info on energy use in a house to try to reduce it.

RunTimers2 driver - rbroders - 09-17-2012

Yeah, integrating over time is a logical extension. I was kind of thinking it belonged in the lighting control driver because that is where all the Dimmer fields live anyway, but I'll give it a shot here just for fun.

It is a bit tricky because of the whole "Running 24HRs" thing. Basically as runs age out of the 24HR window, I still keep an accurate picture of what happened in the current time period.

If your light was on 75% for 12hrs then 25% for 12hrs. For the past 24HRs, the avg weighted on is 50%. However, as time moves forward, if the light stays at 25%, the weighted on value is going to decrease towards 25%. The only way to accurately produce a 24HR weighted pct ON value is by tracking every pct change (and the time it occurred) in the 24HR period (and keeping them in the state file).

Maybe the 24HR sliding window thing is not that useful for this sort of thing and a simply Daily track would be sufficient.

Hmmm -- Bob

RunTimers2 driver - ControlFreak - 09-19-2012

I see the problem you describe.

Maybe have two variables:
* kWhr Today (from midnight last night til current time)
* KWhr Yesterday (last full day from midnight to midnight)

Or, since you appear to be keeping all the events (to generate the strings), just do the math when requested (looking back 24 hours).

Or, just the running timer (what you call "daily") would be good. I presume you have a "reset" command.


RunTimers2 driver - rbroders - 10-25-2013

Added ability to configure the beginning of day for the installer (say you want all your timers to log their history at noon instead of midnight).

Also added Today fields which give you runtime information from the beginning of day until now in addition to the rolling 24HR fields.

Version 2.21 is available in Post #1


RunTimers2 driver - rbroders - 01-24-2014

When I added the "Today" stuff I broke the daily logs. Didn't notice for three months that my system wasn't tracking summary information. Argh. Oh well, if anyone else ever decides to use this driver, it works now in version 2.22. I also changed the logging so unhandled exceptions always get logged (even if verbosity is off). I never notice the reconnects in the driver stats, but I do notice stuff in the logs. Sometimes.

I just installed (fixed) a Ceramic Metal Halide lamp at my house. Amazing thing produces 7,700 lumens off 70W. The only downside is they can explode if they exceed their rated life (16,000Hrs for my bulb). Figured CQC could track the run time for me but then realized my time tracking was broken. Ugh.


RunTimers2 driver - DaveB - 01-24-2014

So the real question is what are you growing with your 7,700 lumen lamp? :-D

RunTimers2 driver - Dean Roddey - 01-24-2014

It's not generally a good thing to log exceptions in any of the higher frequency callbacks. If something goes wrong it can create a deluge of log messages.

If you want something to notify you, use a scheduled event that checks the reconnections field of the drivers you care about, saves them on each round and logs something if the value has gone up by some amount, or something like that.

RunTimers2 driver - rbroders - 01-24-2014

A driver watchdog, I like it! Sounds like something generic enough to add to the architecture eh?

Since unhandled exceptions force a reconnect, the most you'll get is two per second (1 every 4 secs for this driver). Not great, true. I definitely like the driver watchdog better.

BTW, I'd love to have a button to reset driver statistics. When I fix a bug in a driver and restart I'd love to be able to set all the numbers back to zero.


P.S. The light is actually for my dog exercise area.

P.P.S. Just got back from a ski trip to Colorado, but I didn't score any weed. I did notice a bunch of signs at the airport telling you not to take weed out state though ;-)

RunTimers2 driver - Dean Roddey - 01-24-2014

Thought 4.5, and a lot of 5.0, are sort of GUI oriented, one of the things soon up to the plate is going to be a new concept of a 'monitor' or something of that sort. It'll be also hosted in the event server, but will be different from triggered or scheduled events, in that they are persistent, i.e. they continue running, so they can keep track of things much more easily. When that happens, I'll definitely provide some canned ones that you can use, one of which will likely be some sort of system monitor, but you'd be able to write them in CML as well.

This will all be part of the 'make it easier to use' push that is going to dominate what we do for some time to come, and is the driving force behind all of the work we are doing now. There are various sorts of background activities that aren't drivers, that can be done with enough ingenuity with trig/sched events, but aren't convenient or easy to do that way. Having these monitors that you can install and configure with options will make doing these sorts of things much easier.