Monoprice Motion / Temperature Reporting Frequency

The temp readings don’t come In right away on first pairing. If you pair the device and then remove the battery and then reinstall the battery the temperature tile should update.

Also I find these devices only update temp changes every 2 degrees. My smart sense multis update every 1 degree change

Try my updated code, I think I fixed the error.

taken the battery out and it has about about 18 hours still no temp.

Are you using this devicetype

It works for me and I have 6 of these devices. When you look at the IDE Logs and you take the battery out and then put it back in, what do you see in the logs when the device wakes up on battery insert?

I just updated it to incorporate the same integer fix I applied to the Aoen Multisensor above.

I ended up using another code I found and it finally started reporting the temp. I will have to try this code again when i have to chance to sit down and play with it some more.

Works, I’m having a hard time duplicating the functionality for the humidity. I’m device types are interesting to say the least.

Thanks for all the work on this device.

I recently ordered the Monoprice Motion/Temp through Amazon and am using the latest code on this thread. The motion and battery seem to report well, however the temperature (which I set to F) is very wrong. It’s currently reading 176 F in a room that’s more like 78 F. :slight_smile: I’ve tried pulling the battery several times, but it doesn’t seem to help. It’s almost like my unit is reporting in F by default ? Could that be, is there something I’m overlooking.

Thanks…

-James

I just picked up 2 from Monoprice today and they’re doing the same thing (currently 187 and 171)! I have another sensor that I’ve had for about 6 months and it’s reading correctly (77F). All 3 are using the same device type. Incidentally, If I switch the device type to a Aeon Multisensor the same bad readings are registered.

Yep… I actually found a couple references in another thread about the Monoprice sensor now shipping with F readings by default:

In addition to that, the first shipment of the motion sensor used to report its temperature value in degrees Celsius, and the device handler converts that to Fahrenheit. I am not sure if the sensor now ships reporting degrees Fahrenheit from the factory.

So I took the script above and flipped it around for F as the actual reading and convert to C if wanted. Just tried it and it seems to work. If you’d like a copy I can DM you one.

That would be great, thanks!

Recently the device started changing the temp to what appears to be +100 the actual. Seems to happen at night. I removed the battery and it fixed the temp but it went right back that night.

Me too, please! I would like a copy.

I’ll toss the code in the thread here in case others need it some day. All I really changed was the temp conversion math, maybe 5 or 5 lines. Good luck.

/**
 *  Monoprice Motion Sensor - ** Fahrenheit default version **
 *
 *  Capabilities: Motion Sensor, Temperature Measurement, Battery Indicator
 *
 *  Notes: For the Inactivity Timeout to update or Battery level (only for the first time),
 *    you have to open the Motion Sensor and leave it open for a few seconds and then close it.
 *    This triggers the forced Wake up so that the settings can take effect immediately.
 *
 *  Author: FlorianZ,Kranasian, Humac, Moonshine
 *  Date: 2015-09-25
 */
preferences {
    input "inactivityTimeout", "number", title: "Inactivity Timeout", description: "Number of minutes after movement is gone before its reported inactive by the sensor."
    input description: "This feature allows you to correct any temperature variations by selecting an offset. Ex: If your sensor consistently reports a temp that's 5 degrees too warm, you'd enter \"-5\". If 3 degrees too cold, enter \"+3\".", displayDuringSetup: false, type: "paragraph", element: "paragraph"
    input "tempOffset", "number", title: "Temperature Offset", description: "Adjust temperature by this many degrees", range: "*..*", displayDuringSetup: false
    input description: "This feature allows you to change the temperature Unit. If left blank or anything else is typed the default is F.", displayDuringSetup: false, type: "paragraph", element: "paragraph" 
    input "tempUnit", "string", title: "Celsius or Fahrenheit", description: "Temperature Unit (Type C or F)", displayDuringSetup: false
}

metadata {
    definition (name: "Monoprice Motion Sensor", author: "florianz") {
        capability "Battery"
        capability "Motion Sensor"
        capability "Temperature Measurement"
        capability "Sensor"

        fingerprint deviceId:"0x2001", inClusters:"0x71, 0x85, 0x80, 0x72, 0x30, 0x86, 0x31, 0x70, 0x84"
    }

    simulator {
      // messages the device returns in response to commands it receives
      status "motion (basic)"     : "command: 2001, payload: FF"
      status "no motion (basic)"  : "command: 2001, payload: 00"
      status "motion (binary)"    : "command: 3003, payload: FF"
      status "no motion (binary)" : "command: 3003, payload: 00"

      for (int i = 0; i <= 100; i += 20) {
        status "temperature ${i}F": new physicalgraph.zwave.Zwave().sensorMultilevelV2.sensorMultilevelReport(
          scaledSensorValue: i, precision: 1, sensorType: 1, scale: 1).incomingMessage()
      }
      for (int i = 0; i <= 100; i += 20) {
        status "battery ${i}%": new physicalgraph.zwave.Zwave().batteryV1.batteryReport(
          batteryLevel: i).incomingMessage()
      }
    }
        
    tiles {
        standardTile("motion", "device.motion", width: 1, height: 1) {
            state("active", label:'motion', icon:"st.motion.motion.active", backgroundColor:"#53a7c0")
            state("inactive", label:'no motion', icon:"st.motion.motion.inactive", backgroundColor:"#ffffff")
        }

        valueTile("temperature", "device.temperature", inactiveLabel: false, width: 2, height: 2) {
            state "temperature", label:'${currentValue}°',
            backgroundColors:[
                // Celsius Color Range
    [value: 0, color: "#153591"],
    [value: 7, color: "#1e9cbb"],
    [value: 15, color: "#90d2a7"],
    [value: 23, color: "#44b621"],
    [value: 29, color: "#f1d801"],
    [value: 33, color: "#d04e00"],
    [value: 36, color: "#bc2323"],
    // Fahrenheit Color Range
    [value: 40, color: "#153591"],
    [value: 44, color: "#1e9cbb"],
    [value: 59, color: "#90d2a7"],
    [value: 74, color: "#44b621"],
    [value: 84, color: "#f1d801"],
    [value: 92, color: "#d04e00"],
    [value: 96, color: "#bc2323"]
    ]
        }
        
        valueTile("battery", "device.battery", inactiveLabel: false, decoration: "flat") {
            state "battery", label:'${currentValue}% battery', unit:"%"
        }
        main(["motion", "temperature"])
        details(["motion", "temperature", "battery"])
    }
}

def f2c(value) {
    // Given a value in degrees Fahrenheit, return degrees Centigrade

    (value - 32) * 5/9 as float
}

def parse(String description) {
    log.trace "Parse Raw: ${description}"
    def result = []
    // Using reference in: http://www.pepper1.net/zwavedb/device/197
    def cmd = zwave.parse(description, [0x20: 1, 0x80: 1, 0x31: 2, 0x84: 2, 0x71: 1, 0x30: 1])
    if (cmd) {
        if (cmd instanceof physicalgraph.zwave.commands.wakeupv2.WakeUpNotification) {
            result.addAll(sendSettingsUpdate(cmd))
        }
        result << createEvent(zwaveEvent(cmd))
        if (cmd.CMD == "8407") {
            result << new physicalgraph.device.HubAction(zwave.wakeUpV1.wakeUpNoMoreInformation().format())
        }
    }

    log.debug "Parse returned ${result}"
    return result
}

def zwaveEvent(physicalgraph.zwave.commands.wakeupv2.WakeUpNotification cmd) {
    //log.trace "Woke Up!"
    def map = [:]
    map.value = ""
    map.descriptionText = "${device.displayName} woke up."
    return map
}

def sendSettingsUpdate(physicalgraph.zwave.commands.wakeupv2.WakeUpNotification cmd) {
    def inactivityTimeout = (settings.inactivityTimeout == null ?
                             1 : Integer.parseInt(settings.inactivityTimeout))
    def inactivityTimeoutStr = Integer.toString(inactivityTimeout)
    def actions = []
    def lastBatteryUpdate = state.lastBatteryUpdate == null ? 0 : state.lastBatteryUpdate
    if ((new Date().time - lastBatteryUpdate) > 1000 * 60 * 60 * 24) {
        actions.addAll([
            response(zwave.batteryV1.batteryGet().format()),
            [ descriptionText: "Requested battery update from ${device.displayName}.", value: "" ],
            response("delay 600"),
        ])
    }
    actions.addAll([
        response(zwave.configurationV1.configurationSet(
            configurationValue: [inactivityTimeout], defaultValue: False, parameterNumber: 1, size: 1).format()),
        response("delay 600"),
        [ descriptionText: "${device.displayName} was sent inactivity timeout of ${inactivityTimeoutStr}.", value: "" ]
    ])
    actions
}

def zwaveEvent(physicalgraph.zwave.commands.basicv1.BasicSet cmd) {
    def map = [:]
    map.name = "motion"
    map.value = cmd.value ? "active" : "inactive"
    map.handlerName = map.value
    map.descriptionText = cmd.value ? "${device.displayName} detected motion" : "${device.displayName} motion has stopped."
    return map
}

def zwaveEvent(physicalgraph.zwave.commands.sensormultilevelv2.SensorMultilevelReport cmd) {
    def map = [:]
    if (cmd.sensorType == 1) {
        def cmdScale = cmd.scale == 1 ? "F" : "C"
        def preValue = convertTemperatureIfNeeded(cmd.scaledSensorValue, cmdScale, cmd.precision)
        def value = preValue as float
        map.unit = tempUnit
      map.name = "temperature"
 
        switch(tempUnit) {
            case ["C","c"]:
        if (tempOffset) {
                  def offset = tempOffset as float
              map.value = f2c(value) + offset as float
                }
                else {
                  map.value = f2c(value) as float
                }  
                map.value = map.value.round()
                map.descriptionText = "${device.displayName} temperature is ${map.value} °${map.unit}."
      break
                
            case ["F","f"]:
              if (tempOffset) {
                  def offset = tempOffset as float
              map.value = value + offset as float
                }
                else {
                  map.value = value as float
                }    
                map.value = map.value.round()
                map.descriptionText = "${device.displayName} temperature is ${map.value} °${map.unit}."
                break
            
            default:
              if (tempOffset) {
                  def offset = tempOffset as float
              map.value = value + offset as float
                }
                else {
                  map.value = value as float
                }    
                map.value = map.value.round()
                map.descriptionText = "${device.displayName} temperature is ${map.value} °${map.unit}."
                break    
  }   
    }
    map
}

def zwaveEvent(physicalgraph.zwave.commands.batteryv1.BatteryReport cmd) {
    state.lastBatteryUpdate = new Date().time
    def map = [ name: "battery", unit: "%" ]
    if (cmd.batteryLevel == 0xFF || cmd.batteryLevel == 0 ) {
        map.value = 1
        map.descriptionText = "${device.displayName} battery is almost dead!"
    } else if (cmd.batteryLevel < 15 ) {
        map.value = cmd.batteryLevel
        map.descriptionText = "${device.displayName} battery is low!"
    } else {
        map.value = cmd.batteryLevel
    }
    map
}

def zwaveEvent(physicalgraph.zwave.Command cmd) {
    // Catch-all handler. The sensor does return some alarm values, which
    // could be useful if handled correctly (tamper alarm, etc.)
    [descriptionText: "Unhandled: ${device.displayName}: ${cmd}", displayed: false]
}

@Moonshine
Thanks for this device type.
I just tried it, and it is showing temp and motion, but for the battery field, it only shows two dashes –

Do you think (or know) there a longer delay on reporting battery than the other things, and that’s what’s happening?
I will report back if it changes after letting it sit there a while…

UPDATE: It is indeed reporting battery now. So, thanks a bunch, @Moonshine :slight_smile:

Yeah… I haven’t seen battery specifically, but the unit does seems a little slow to poll/report changes like temp. Haven’t had a chance to see if that could be tweaked somehow. Anyways, enjoy. :slight_smile:

Thank you very much!

I have 2 of the GoControl motion detectors (both are using the custom My Monoprice motion sensor v2 device type). One works great and shows battery and the other no matter what I have tried only shows motion and temp. I did not find a sure way through reading this thread that anyone found that will fix this. I see the comments on wait and eventually it will show up. I guess I will wait as it has only been 4 hours since I added it into my Hub.

I waited about 2 weeks and mine never reported.
I popped the cover off one and pulled the battery and put it back in, still nothing.
These aren’t being used anywhere that it’s critical, daily automation.

Just seems very odd that some work and others don’t show battery :roll_eyes:

Sorry if this is a newbie question, but after pasting in that code at my logged-in Developer console at New SmartApp code, I’m getting this error:

No signature of method: script1478579845094637088962.metadata() is applicable for argument types: (script1478579845094637088962$_run_closure2) values: [script1478579845094637088962$_run_closure2@274f7280] Possible solutions: getMetadata(), getState(), setState(java.lang.Object), metaClass(groovy.lang.Closure)

Desperate for help! What does this mean? Thanks.