latestValue() vs currentValue()

I use lock0.latestValue(“lock”) for my Schlage …
can somebody explain the difference between them?

also how do i get real time (live) stat of Device and not the last reported one??


You actually can just use lock.currentLock.

current is the documented method to get this value.

See the documentation here:


Sorry, there really is no way to know if you have the “real time” vs “previously reported” state. That’s simply the nature of ST’s architecture – everything is in lag time and asynchronous. At any given moment, the “real world” state vs the “ST world” state is non-deterministic. Makes it fun. :grinning:

1 Like

@bravenel is right on.

These methods really do the same thing:


And as Bruce says, all of these get the most recently reported attribute value from the device.


Didn’t know that…now i do!

Sometimes this lock.currentLock reports “null” rather than “locked” or “unlocked”…

I’m not sure why this happens, but it makes it difficult to determine the status of the lock when the open/close sensor fires the “open” event and the lock.currentLock reports “null”.

Any thoughts?

I’ve seen this before too. When I traced it down, the lock device type was actually reporting “null”. Apparently, this is a valid state of the lock sometimes.

As a programmer depending on a binary result from calling this function, “null” is not a valid state, but apparently follows the warning stated below in the ST documentation.

IMHO, one cannot provide any automation logic if the state of the device is “null”, other than to flip a coin and guess that the device is either on/off, locked/unlocked, closed/opened, motion/nomotion, etc…


Get the latest reported value for the specified attribute.


Object latestValue(String attributeName)


String attributeName - the name of the attribute to get the latest value for.


Object - the latest reported value. The exact type returned will vary depending upon the attribute.


The exact returned type for various attributes is not adequately documented at this time. Until they are, we recommend that you save often and experiment, or even look at the specific Device Handler for the device you are working with.

I think that there is an issue with the first time this function is called for selected devices and after that first call where null is returned, it appears that the “state” of the device is populated when it has thrown an event.

Hi Kurt - yes, I think the device state is null before it gets its first result.

However, the point I was trying to make is that the lock device itself may report a null state. In fact, I think it can report a range of states other than locked/unlocked including locking/unlocking, error and null.

I am wondering if the “null” value of latestvalue() state is being mapped to “unknown” condition below in ST’s “Z-Wave lock” device code. The description for “unknown” are only these two states in the device driver:

  • "$device.displayName was not locked fully
  • “$device.displayName is jammed”

The lock state of “unknown” is apparently being expected in the SmartTile block and the 0x40 state code returned from the lock:

  tiles(scale: 2) {
    multiAttributeTile(name:"toggle", type: "generic", width: 6, height: 4){
      tileAttribute ("device.lock", key: "PRIMARY_CONTROL") {
        attributeState "locked", label:'locked', action:"lock.unlock", icon:"st.locks.lock.locked", backgroundColor:"#79b821", nextState:"unlocking"
        attributeState "unlocked", label:'unlocked', action:"lock.lock", icon:"st.locks.lock.unlocked", backgroundColor:"#ffffff", nextState:"locking"
        attributeState "unknown", label:"unknown", action:"lock.lock", icon:"st.locks.lock.unknown", backgroundColor:"#ffffff", nextState:"locking"
        attributeState "locking", label:'locking', icon:"st.locks.lock.locked", backgroundColor:"#79b821"
        attributeState "unlocking", label:'unlocking', icon:"st.locks.lock.unlocked", backgroundColor:"#ffffff"

def zwaveEvent(DoorLockOperationReport cmd) {
  def result = []
  def map = [ name: "lock" ]
  if (cmd.doorLockMode == 0xFF) {
    map.value = "locked"
  } else if (cmd.doorLockMode >= 0x40) {
    map.value = "unknown"
  } else if (cmd.doorLockMode & 1) {
    map.value = "unlocked with timeout"
  } else {
    map.value = "unlocked"
    if (state.assoc != zwaveHubNodeId) {
      log.debug "setting association"
      result << response(secure(zwave.associationV1.associationSet(groupingIdentifier:1, nodeId:zwaveHubNodeId)))
      result << response(zwave.associationV1.associationSet(groupingIdentifier:2, nodeId:zwaveHubNodeId))
      result << response(secure(zwave.associationV1.associationGet(groupingIdentifier:1)))
  result ? [createEvent(map), *result] : createEvent(map)
1 Like

When using device.currentValue('status') on a musicPlayer deviceType, I consistently received “stopped” when the device was playing, even though I could see the device returning “playing” in the devices live logs.

When using device.latestValue('status') on the same device, I consistently received “playing” when it was playing and “stopped” when it was stopped.

There does seem to be some difference between these variables.

1 Like

That’s strange. Without seeing al the code and trying to reproduce I don’t know why that would be. They call the exact same system API behind the scenes. I’d have to look more at this specific case to know why that might be happening.

If you care to take a look…

Specifically, I was calling currentValue('status') in my Big Talker SmartApp (Version 1.1.3) line 2795 (within the Talk() function). It would write back the value to LiveLogging at line 2802, 2825, or 2836 depending on the conditions. The returned value was always “stopped” even though the musicPlayer device was playing and the device’s logs showed “playing” was returned. In my current development version (1.1.3-GREG4,, I switched to using “latestValue(‘status’)” and received the results I needed (showing ‘playing’ or ‘stopped’ accurately) for proper analysis and further execution.

My musicPlayer device/deviceType is Geko’s VLCThing which shows “playing” in LiveLogging when it is playing and returns properly with latestValue('status'). ( ).