App: Device Tracker, Multiple Device On/Off Times, On Counts, Notifier, Battery Levels, Switches, Contacts, Temperatures, Power, etc.. With variables access

Thanks for this.
It will be great if the table can be expanded/renamed to include the following perhaps:
Current Active Time, Previous Day Active Time, Weekly Active Time, Monthly Active Time

Also, not sure why the time is messed up for Bathroom Light1?

My Lights usage table

I've seen those crazy times on occasion. Tracking down the issue is on going, difficult since it doesn't happen all the time. Will think about how to add days, weeks, etc..

3 Likes

Watching with interest!

Cheers,

Thanks for great app!

How about tracking a device based on the Power monitoring capability? For example, many electronic devices draw a small amount of power when they are in 'standby' mode. I don't want to track that as active time. But if the power goes above a threshold (a few watts typically) then I want to track that as 'active' time until it drops back down to the 'standby' power level

OK, Power monitoring added. Track time a device is using power above a entered threshold. Copy and paste Parent and Child app code from github link above.

2 Likes

I just tried to add & run your app & get this error msg. I copied both Parent/Child code from your GitHub repo. (Raw) into Hubitat. Thoughts as to what the fix is?

I just uninstalled mine and re-installed from Github and no issue.
-From Apps page: Deleted all old "Device Time tracker" and "Device Time tracker child "apps
-From Apps Code page: Deleted all old "Device Time tracker" and "Device Time tracker child "apps
-Copy and paste both new Github "Device Time tracker" and "Device Time tracker child "apps to Apps code page
-From apps added user App, click on "Device time Tracker"
-Use app, child will automatically be created.

Thank you @kampto ,
I was looking for this functionality. I have previously created my own set of rules in RM to measure and present my Watering valves and Boiler OPEN times.
I will try and replace them with your app as it seems more orginized and easy to use.
Thanks again.

Hi @kampto ,
I am trying to use this app to keep track for how long (since last reset) a valve or a boiler were ON.
In order to present this info on a dashboard I understand I need to create a string hub variable and connect it in the app to the relevant device I am tracking.
I can see the variable gets refreshed when I click refresh on the app screen or when the device changes status (from ON to OFF for example).
As the valve or boiler might be ON for a long time before it closes and I might be interested in seeing real live data, is it possible to add a refresh command every a defined period (say allow refresh every X minutes). Iassume this can be done using RM (refresh command) but I think it will be logical to add it to the app setup.
What say you?
Edit - thinking it through I think the requirement is only needed while the device is active.

A while back I tried to figure out how to get the variable to refresh periodically or on state change without going into the app and hitting refresh. Its something I want also. But was unsuccessful. Will think about it some more.
Maybe someone with more code skills can provide some insight!

Thanks you for that.
I think @thebearmay might be able to help here.
@thebearmay, hope you will not find ut rude of me asking for your help.

For a refresh on state change you'll want to subscribe to the event for an attribute, and then trigger the update

subscribe(device, attributeName, handlerMethod)
...
def handlerMethod(evt) {
///refresh logic
}

For a regular update based on time

runIn(numSeconds, handlerMethod) 
...
def handlerMethod() {
///refresh logic
}
2 Likes

Here are your methods for status changes:

void onHandler(evt) {
	state.lights[evt.device.id].start = now()
        }

void offHandler(evt) {
	state.lights[evt.device.id].total += now() - state.lights[evt.device.id].start
	String thisVar = state.lights[evt.device.id].var
	if(thisVar) {
		int total = state.lights[evt.device.id].total / 1000
		int hours = total / 3600
		total = total % 3600
		int mins = total / 60
		int secs = total % 60
		setGlobalVar(thisVar, "$hours:${mins < 10 ? "0" : ""}$mins:${secs < 10 ? "0" : ""}$secs")
	}
}

The variable is only updated once the offHandler method is called. That would be when the light is turned off, contact closed, etc.. You'll need a refresh method like @thebearmay hinted to, that will refresh the "on" time and update the variable periodically.

You actually already have the logic in the button handler:

    else if (btn == "refresh") state.lights.each {k, v ->
		def dev = lights.find{"$it.id" == k}
        
        if (capabilitySelect == "1" && dev.currentSwitch == "on") {
        	state.lights[k].total += now() - state.lights[k].start
			state.lights[k].start = now()
		    }
        else if (capabilitySelect == "2" && dev.currentContact == "open") {
        	state.lights[k].total += now() - state.lights[k].start
			state.lights[k].start = now()
		    }
       else if (capabilitySelect == "3" && dev.currentContact == "closed") {
        	state.lights[k].total += now() - state.lights[k].start
			state.lights[k].start = now()
		    }
       else if (capabilitySelect == "4" && dev.currentPower >= powerThreshold) {
        	state.lights[k].total += now() - state.lights[k].start
			state.lights[k].start = now()
		    } 
       endif
       }
1 Like

I will mess around with it tonight and see if it can get done.

2 Likes

Who needs ChatGPT when you have this great community help? :clap::clap::clap:

1 Like

Variable refresh is added now, figured out where I went wrong previous try. Copy paste the updated child app code. You might have to delete existing child apps and re-make for it to work. You can see the refresh in the logs.

2 Likes

Hi @kampto ,
I can confirm that the refresh every X minutes is working.
A couple of questions,

  1. What is the meaning of "after the hour" in the text for the auto update?
  2. I did not see a refresh variable log when the measured device is closed.
    In order to reserve CPU it would be better if the refresh every X minute will happen only while the relevant device is ON (or OPEN or in the state you are timing). When the timed status is CLOSE it should send a refresh command to the variable attached and stop refreshing till next measured status happen.
    Does this make sence?
  1. Im using a CRON for the refresh, so if you picked 2, that would be 2, 4, 6,.. Min after the hour. So 7:00, 7:02, 7:04, etc.. if the hour is 7. If you picked 30 then 7:00, 7:30. 8:00, 8:30,...

  2. I just now added a log for device Inactive or Off. It updates variable every time it goes to the Off state, its always worked that way. Periodic updates keep you informed if its changed open or closed. I doubt the CPU usage will be high but your check the log stats. But I can look into it for On only.

Im thinking of adding an bool Option to have the time tracker variable written as a number in total seconds so it can be used in a rule rather then just displayed in string time format. "String format in time" or "number format in total seconds". Then you could use RM trigger things based on how long a device has been on or off.

2 Likes

I think you are right and other people might find it useful.
Me personally, I will stick to the string as I am mostly interested in displaying the variable value in a HH:MM:SS format.